include/fileutils.h \
include/idcache.h \
include/ismounted.h \
+ include/pwdutils.h \
include/linux_version.h \
include/list.h \
include/loopdev.h \
--- /dev/null
+#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 */
+
lib/pager.c \
lib/parse-date.y \
lib/path.c \
+ lib/pwdutils.c \
lib/randutils.c \
lib/setproctitle.c \
lib/strutils.c \
test_colors \
test_fileutils \
test_ismounted \
+ test_pwdutils \
test_mangle \
test_randutils \
test_strutils \
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
--- /dev/null
+#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 */
#include "all-io.h"
#include "fileutils.h"
#include "ttyutils.h"
+#include "pwdutils.h"
#include "logindefs.h"
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 */
}
}
-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)
{
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() */
*/
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__);