123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- From 295bf7403364b23ab03287ecdd95ea266d6f4d89 Mon Sep 17 00:00:00 2001
- From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
- Date: Thu, 11 Jun 2020 17:39:03 +0200
- Subject: [PATCH] fix build on musl
- Rename check_user_in_passwd from pam_localuser.c to
- pam_modutil_check_user_in_passwd and use it in pam_faillock.c instead of
- fgetpwent_r which is not available on musl
- Fix #236
- Fixes:
- - http://autobuild.buildroot.org/results/0432736ffee376dd84757469434a4bbcfdcdaf4b
- Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
- [Upstream status: https://github.com/linux-pam/linux-pam/pull/237]
- ---
- libpam/Makefile.am | 1 +
- libpam/include/security/pam_modutil.h | 5 ++
- libpam/libpam.map | 5 ++
- libpam/pam_modutil_check_user_in_passwd.c | 89 +++++++++++++++++++++++
- modules/pam_faillock/pam_faillock.c | 37 +---------
- modules/pam_localuser/pam_localuser.c | 86 +---------------------
- 6 files changed, 103 insertions(+), 120 deletions(-)
- create mode 100644 libpam/pam_modutil_check_user_in_passwd.c
- diff --git a/libpam/Makefile.am b/libpam/Makefile.am
- index 9252a837..a8fc428d 100644
- --- a/libpam/Makefile.am
- +++ b/libpam/Makefile.am
- @@ -35,6 +35,7 @@ libpam_la_SOURCES = pam_account.c pam_auth.c pam_data.c pam_delay.c \
- pam_misc.c pam_password.c pam_prelude.c \
- pam_session.c pam_start.c pam_strerror.c \
- pam_vprompt.c pam_syslog.c pam_dynamic.c pam_audit.c \
- + pam_modutil_check_user_in_passwd.c \
- pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \
- pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \
- pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c \
- diff --git a/libpam/include/security/pam_modutil.h b/libpam/include/security/pam_modutil.h
- index 3a6aec6a..33f87b90 100644
- --- a/libpam/include/security/pam_modutil.h
- +++ b/libpam/include/security/pam_modutil.h
- @@ -58,6 +58,11 @@ extern "C" {
-
- #include <security/_pam_types.h>
-
- +extern int PAM_NONNULL((1,2))
- +pam_modutil_check_user_in_passwd(pam_handle_t *pamh,
- + const char *user_name,
- + const char *file_name);
- +
- extern struct passwd * PAM_NONNULL((1,2))
- pam_modutil_getpwnam(pam_handle_t *pamh, const char *user);
-
- diff --git a/libpam/libpam.map b/libpam/libpam.map
- index c9690a91..3cc7ef35 100644
- --- a/libpam/libpam.map
- +++ b/libpam/libpam.map
- @@ -82,3 +82,8 @@ LIBPAM_1.4 {
- global:
- pam_start_confdir;
- } LIBPAM_1.0;
- +
- +LIBPAM_MODUTIL_1.4.1 {
- + global:
- + pam_modutil_check_user_in_passwd;
- +} LIBPAM_MODUTIL_1.3.2;
- diff --git a/libpam/pam_modutil_check_user_in_passwd.c b/libpam/pam_modutil_check_user_in_passwd.c
- new file mode 100644
- index 00000000..b998aa25
- --- /dev/null
- +++ b/libpam/pam_modutil_check_user_in_passwd.c
- @@ -0,0 +1,89 @@
- +#include "pam_modutil_private.h"
- +#include <security/pam_ext.h>
- +
- +#include <stdio.h>
- +#include <syslog.h>
- +
- +int
- +pam_modutil_check_user_in_passwd(pam_handle_t *pamh,
- + const char *user_name,
- + const char *file_name)
- +{
- + int rc;
- + size_t user_len;
- + FILE *fp;
- + char line[BUFSIZ];
- +
- + /* Validate the user name. */
- + if ((user_len = strlen(user_name)) == 0) {
- + pam_syslog(pamh, LOG_NOTICE, "user name is not valid");
- + return PAM_SERVICE_ERR;
- + }
- +
- + if (user_len > sizeof(line) - sizeof(":")) {
- + pam_syslog(pamh, LOG_NOTICE, "user name is too long");
- + return PAM_SERVICE_ERR;
- + }
- +
- + if (strchr(user_name, ':') != NULL) {
- + /*
- + * "root:x" is not a local user name even if the passwd file
- + * contains a line starting with "root:x:".
- + */
- + return PAM_PERM_DENIED;
- + }
- +
- + /* Open the passwd file. */
- + if (file_name == NULL) {
- + file_name = "/etc/passwd";
- + }
- + if ((fp = fopen(file_name, "r")) == NULL) {
- + pam_syslog(pamh, LOG_ERR, "error opening %s: %m", file_name);
- + return PAM_SERVICE_ERR;
- + }
- +
- + /*
- + * Scan the file using fgets() instead of fgetpwent_r() because
- + * the latter is not flexible enough in handling long lines
- + * in passwd files.
- + */
- + rc = PAM_PERM_DENIED;
- + while (fgets(line, sizeof(line), fp) != NULL) {
- + size_t line_len;
- + const char *str;
- +
- + /*
- + * Does this line start with the user name
- + * followed by a colon?
- + */
- + if (strncmp(user_name, line, user_len) == 0 &&
- + line[user_len] == ':') {
- + rc = PAM_SUCCESS;
- + break;
- + }
- + /* Has a newline been read? */
- + line_len = strlen(line);
- + if (line_len < sizeof(line) - 1 ||
- + line[line_len - 1] == '\n') {
- + /* Yes, continue with the next line. */
- + continue;
- + }
- +
- + /* No, read till the end of this line first. */
- + while ((str = fgets(line, sizeof(line), fp)) != NULL) {
- + line_len = strlen(line);
- + if (line_len == 0 ||
- + line[line_len - 1] == '\n') {
- + break;
- + }
- + }
- + if (str == NULL) {
- + /* fgets returned NULL, we are done. */
- + break;
- + }
- + /* Continue with the next line. */
- + }
- +
- + fclose(fp);
- + return rc;
- +}
- diff --git a/modules/pam_faillock/pam_faillock.c b/modules/pam_faillock/pam_faillock.c
- index f592d0a2..8bca46ca 100644
- --- a/modules/pam_faillock/pam_faillock.c
- +++ b/modules/pam_faillock/pam_faillock.c
- @@ -348,42 +348,7 @@ set_conf_opt(pam_handle_t *pamh, struct options *opts, const char *name, const c
- static int
- check_local_user (pam_handle_t *pamh, const char *user)
- {
- - struct passwd pw, *pwp;
- - char buf[16384];
- - int found = 0;
- - FILE *fp;
- - int errn;
- -
- - fp = fopen(PATH_PASSWD, "r");
- - if (fp == NULL) {
- - pam_syslog(pamh, LOG_ERR, "unable to open %s: %m",
- - PATH_PASSWD);
- - return -1;
- - }
- -
- - for (;;) {
- - errn = fgetpwent_r(fp, &pw, buf, sizeof (buf), &pwp);
- - if (errn == ERANGE) {
- - pam_syslog(pamh, LOG_WARNING, "%s contains very long lines; corrupted?",
- - PATH_PASSWD);
- - break;
- - }
- - if (errn != 0)
- - break;
- - if (strcmp(pwp->pw_name, user) == 0) {
- - found = 1;
- - break;
- - }
- - }
- -
- - fclose (fp);
- -
- - if (errn != 0 && errn != ENOENT) {
- - pam_syslog(pamh, LOG_ERR, "unable to enumerate local accounts: %m");
- - return -1;
- - } else {
- - return found;
- - }
- + return pam_modutil_check_user_in_passwd(pamh, user, NULL);
- }
-
- static int
- diff --git a/modules/pam_localuser/pam_localuser.c b/modules/pam_localuser/pam_localuser.c
- index cb507524..a9f2233c 100644
- --- a/modules/pam_localuser/pam_localuser.c
- +++ b/modules/pam_localuser/pam_localuser.c
- @@ -45,92 +45,10 @@
- #include <unistd.h>
-
- #include <security/pam_modules.h>
- +#include <security/pam_modutil.h>
- #include <security/pam_ext.h>
- #include "pam_inline.h"
-
- -static int
- -check_user_in_passwd(pam_handle_t *pamh, const char *user_name,
- - const char *file_name)
- -{
- - int rc;
- - size_t user_len;
- - FILE *fp;
- - char line[BUFSIZ];
- -
- - /* Validate the user name. */
- - if ((user_len = strlen(user_name)) == 0) {
- - pam_syslog(pamh, LOG_NOTICE, "user name is not valid");
- - return PAM_SERVICE_ERR;
- - }
- -
- - if (user_len > sizeof(line) - sizeof(":")) {
- - pam_syslog(pamh, LOG_NOTICE, "user name is too long");
- - return PAM_SERVICE_ERR;
- - }
- -
- - if (strchr(user_name, ':') != NULL) {
- - /*
- - * "root:x" is not a local user name even if the passwd file
- - * contains a line starting with "root:x:".
- - */
- - return PAM_PERM_DENIED;
- - }
- -
- - /* Open the passwd file. */
- - if (file_name == NULL) {
- - file_name = "/etc/passwd";
- - }
- - if ((fp = fopen(file_name, "r")) == NULL) {
- - pam_syslog(pamh, LOG_ERR, "error opening %s: %m", file_name);
- - return PAM_SERVICE_ERR;
- - }
- -
- - /*
- - * Scan the file using fgets() instead of fgetpwent_r() because
- - * the latter is not flexible enough in handling long lines
- - * in passwd files.
- - */
- - rc = PAM_PERM_DENIED;
- - while (fgets(line, sizeof(line), fp) != NULL) {
- - size_t line_len;
- - const char *str;
- -
- - /*
- - * Does this line start with the user name
- - * followed by a colon?
- - */
- - if (strncmp(user_name, line, user_len) == 0 &&
- - line[user_len] == ':') {
- - rc = PAM_SUCCESS;
- - break;
- - }
- - /* Has a newline been read? */
- - line_len = strlen(line);
- - if (line_len < sizeof(line) - 1 ||
- - line[line_len - 1] == '\n') {
- - /* Yes, continue with the next line. */
- - continue;
- - }
- -
- - /* No, read till the end of this line first. */
- - while ((str = fgets(line, sizeof(line), fp)) != NULL) {
- - line_len = strlen(line);
- - if (line_len == 0 ||
- - line[line_len - 1] == '\n') {
- - break;
- - }
- - }
- - if (str == NULL) {
- - /* fgets returned NULL, we are done. */
- - break;
- - }
- - /* Continue with the next line. */
- - }
- -
- - fclose(fp);
- - return rc;
- -}
- -
- int
- pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
- int argc, const char **argv)
- @@ -173,7 +91,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
- return rc == PAM_CONV_AGAIN ? PAM_INCOMPLETE : rc;
- }
-
- - return check_user_in_passwd(pamh, user_name, file_name);
- + return pam_modutil_check_user_in_passwd(pamh, user_name, file_name);
- }
-
- int
- --
- 2.26.2
|