]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
login: add xgetpwnam()
authorKarel Zak <kzak@redhat.com>
Fri, 14 Oct 2016 11:21:17 +0000 (13:21 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 18 Sep 2017 09:48:56 +0000 (11:48 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
include/Makemodule.am
include/pwdutils.h [new file with mode: 0644]
lib/Makemodule.am
lib/pwdutils.c [new file with mode: 0644]
login-utils/login.c

index bed548908560707cc2509b7b1ad6453056171601..2415b0ed820e91380a55df3a165468d1b97514f6 100644 (file)
@@ -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 (file)
index 0000000..c2967d3
--- /dev/null
@@ -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 */
+
index 73ac9a6f5526d8fbe72cdd4d3ec1a851ad6b36bc..5a692b7b7c615e929254a07a10a239f37d1bfc8a 100644 (file)
@@ -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 (file)
index 0000000..58e75a4
--- /dev/null
@@ -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 */
index 9bc1bd9c466d7c7497653bf570a57aa93c4e9d86..7f311536efa1774bd47cf1233774591fd5fd3ead 100644 (file)
@@ -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__);