summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak2016-10-14 13:21:17 +0200
committerKarel Zak2017-09-18 11:48:56 +0200
commit4f5f35fc83067b2c4874fce00ea0b53ef2488489 (patch)
tree78a973ea1f65700bdd1ce891e6ad83bbf43194ca
parentsu: consolidate tty name usage (diff)
downloadkernel-qcow2-util-linux-4f5f35fc83067b2c4874fce00ea0b53ef2488489.tar.gz
kernel-qcow2-util-linux-4f5f35fc83067b2c4874fce00ea0b53ef2488489.tar.xz
kernel-qcow2-util-linux-4f5f35fc83067b2c4874fce00ea0b53ef2488489.zip
login: add xgetpwnam()
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--include/Makemodule.am1
-rw-r--r--include/pwdutils.h10
-rw-r--r--lib/Makemodule.am5
-rw-r--r--lib/pwdutils.c64
-rw-r--r--login-utils/login.c29
5 files changed, 85 insertions, 24 deletions
diff --git a/include/Makemodule.am b/include/Makemodule.am
index bed548908..2415b0ed8 100644
--- a/include/Makemodule.am
+++ b/include/Makemodule.am
@@ -19,6 +19,7 @@ dist_noinst_HEADERS += \
include/fileutils.h \
include/idcache.h \
include/ismounted.h \
+ include/pwdutils.h \
include/linux_version.h \
include/list.h \
include/loopdev.h \
diff --git a/include/pwdutils.h b/include/pwdutils.h
new file mode 100644
index 000000000..c2967d315
--- /dev/null
+++ b/include/pwdutils.h
@@ -0,0 +1,10 @@
+#ifndef UTIL_LINUX_PWDUTILS_H
+#define UTIL_LINUX_PWDUTILS_H
+
+#include <sys/types.h>
+#include <pwd.h>
+
+extern struct passwd *xgetpwnam(const char *username, char **pwdbuf);
+
+#endif /* UTIL_LINUX_PWDUTILS_H */
+
diff --git a/lib/Makemodule.am b/lib/Makemodule.am
index 73ac9a6f5..5a692b7b7 100644
--- a/lib/Makemodule.am
+++ b/lib/Makemodule.am
@@ -18,6 +18,7 @@ libcommon_la_SOURCES = \
lib/pager.c \
lib/parse-date.y \
lib/path.c \
+ lib/pwdutils.c \
lib/randutils.c \
lib/setproctitle.c \
lib/strutils.c \
@@ -74,6 +75,7 @@ check_PROGRAMS += \
test_colors \
test_fileutils \
test_ismounted \
+ test_pwdutils \
test_mangle \
test_randutils \
test_strutils \
@@ -149,3 +151,6 @@ test_canonicalize_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_CANONICALIZE
test_timeutils_SOURCES = lib/timeutils.c lib/strutils.c
test_timeutils_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_TIMEUTILS
+
+test_pwdutils_SOURCES = lib/pwdutils.c
+test_pwdutils_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM
diff --git a/lib/pwdutils.c b/lib/pwdutils.c
new file mode 100644
index 000000000..58e75a45b
--- /dev/null
+++ b/lib/pwdutils.c
@@ -0,0 +1,64 @@
+#include <stdlib.h>
+
+#include "c.h"
+#include "pwdutils.h"
+#include "xalloc.h"
+
+/* Returns allocated passwd and allocated pwdbuf to store passwd strings
+ * fields. In case of error returns NULL and set errno, for unknown user set
+ * errno to EINVAL
+ */
+struct passwd *xgetpwnam(const char *username, char **pwdbuf)
+{
+ struct passwd *pwd = NULL, *res = NULL;
+ int rc;
+
+ if (!pwdbuf || !username)
+ return NULL;
+
+ *pwdbuf = xmalloc(UL_GETPW_BUFSIZ);
+ pwd = xcalloc(1, sizeof(struct passwd));
+
+ errno = 0;
+ rc = getpwnam_r(username, pwd, *pwdbuf, UL_GETPW_BUFSIZ, &res);
+ if (rc != 0) {
+ errno = rc;
+ goto failed;
+ }
+ if (!res) {
+ errno = EINVAL;
+ goto failed;
+ }
+ return pwd;
+failed:
+ free(pwd);
+ free(*pwdbuf);
+ return NULL;
+}
+
+
+#ifdef TEST_PROGRAM
+int main(int argc, char *argv[])
+{
+ char *pwdbuf = NULL;
+ struct passwd *pwd = NULL;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <username>\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ pwd = xgetpwnam(argv[1], &pwdbuf);
+ if (!pwd)
+ err(EXIT_FAILURE, "failed to get %s pwd entry", argv[1]);
+
+ printf("Username: %s\n", pwd->pw_name);
+ printf("UID: %d\n", pwd->pw_uid);
+ printf("HOME: %s\n", pwd->pw_dir);
+ printf("GECO: %s\n", pwd->pw_gecos);
+
+ free(pwd);
+ free(pwdbuf);
+ return EXIT_SUCCESS;
+}
+#endif /* TEST_PROGRAM */
diff --git a/login-utils/login.c b/login-utils/login.c
index 9bc1bd9c4..7f311536e 100644
--- a/login-utils/login.c
+++ b/login-utils/login.c
@@ -77,6 +77,7 @@
#include "all-io.h"
#include "fileutils.h"
#include "ttyutils.h"
+#include "pwdutils.h"
#include "logindefs.h"
@@ -107,6 +108,7 @@ struct login_context {
char *username; /* from command line or PAM */
struct passwd *pwd; /* user info */
+ char *pwdbuf; /* pwd strings */
pam_handle_t *pamh; /* PAM handler */
struct pam_conv conv; /* PAM conversation */
@@ -652,26 +654,6 @@ static void log_syslog(struct login_context *cxt)
}
}
-static struct passwd *get_passwd_entry(const char *username,
- char **pwdbuf,
- struct passwd *pwd)
-{
- struct passwd *res = NULL;
- int x;
-
- if (!pwdbuf || !username)
- return NULL;
-
- *pwdbuf = xrealloc(*pwdbuf, UL_GETPW_BUFSIZ);
-
- x = getpwnam_r(username, pwd, *pwdbuf, UL_GETPW_BUFSIZ, &res);
- if (!res) {
- errno = x;
- return NULL;
- }
- return res;
-}
-
/* encapsulate stupid "void **" pam_get_item() API */
static int loginpam_get_username(pam_handle_t *pamh, char **name)
{
@@ -1129,9 +1111,7 @@ int main(int argc, char **argv)
int childArgc = 0;
int retcode;
struct sigaction act;
-
- char *pwdbuf = NULL;
- struct passwd *pwd = NULL, _pwd;
+ struct passwd *pwd;
struct login_context cxt = {
.tty_mode = TTY_MODE, /* tty chmod() */
@@ -1243,7 +1223,8 @@ int main(int argc, char **argv)
*/
loginpam_acct(&cxt);
- if (!(cxt.pwd = get_passwd_entry(cxt.username, &pwdbuf, &_pwd))) {
+ cxt.pwd = xgetpwnam(cxt.username, &cxt.pwdbuf);
+ if (!cxt.pwd) {
warnx(_("\nSession setup problem, abort."));
syslog(LOG_ERR, _("Invalid user name \"%s\" in %s:%d. Abort."),
cxt.username, __FUNCTION__, __LINE__);