0002-fix-build-on-musl.patch 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. From 295bf7403364b23ab03287ecdd95ea266d6f4d89 Mon Sep 17 00:00:00 2001
  2. From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
  3. Date: Thu, 11 Jun 2020 17:39:03 +0200
  4. Subject: [PATCH] fix build on musl
  5. Rename check_user_in_passwd from pam_localuser.c to
  6. pam_modutil_check_user_in_passwd and use it in pam_faillock.c instead of
  7. fgetpwent_r which is not available on musl
  8. Fix #236
  9. Fixes:
  10. - http://autobuild.buildroot.org/results/0432736ffee376dd84757469434a4bbcfdcdaf4b
  11. Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
  12. [Upstream status: https://github.com/linux-pam/linux-pam/pull/237]
  13. ---
  14. libpam/Makefile.am | 1 +
  15. libpam/include/security/pam_modutil.h | 5 ++
  16. libpam/libpam.map | 5 ++
  17. libpam/pam_modutil_check_user_in_passwd.c | 89 +++++++++++++++++++++++
  18. modules/pam_faillock/pam_faillock.c | 37 +---------
  19. modules/pam_localuser/pam_localuser.c | 86 +---------------------
  20. 6 files changed, 103 insertions(+), 120 deletions(-)
  21. create mode 100644 libpam/pam_modutil_check_user_in_passwd.c
  22. diff --git a/libpam/Makefile.am b/libpam/Makefile.am
  23. index 9252a837..a8fc428d 100644
  24. --- a/libpam/Makefile.am
  25. +++ b/libpam/Makefile.am
  26. @@ -35,6 +35,7 @@ libpam_la_SOURCES = pam_account.c pam_auth.c pam_data.c pam_delay.c \
  27. pam_misc.c pam_password.c pam_prelude.c \
  28. pam_session.c pam_start.c pam_strerror.c \
  29. pam_vprompt.c pam_syslog.c pam_dynamic.c pam_audit.c \
  30. + pam_modutil_check_user_in_passwd.c \
  31. pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \
  32. pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \
  33. pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c \
  34. diff --git a/libpam/include/security/pam_modutil.h b/libpam/include/security/pam_modutil.h
  35. index 3a6aec6a..33f87b90 100644
  36. --- a/libpam/include/security/pam_modutil.h
  37. +++ b/libpam/include/security/pam_modutil.h
  38. @@ -58,6 +58,11 @@ extern "C" {
  39. #include <security/_pam_types.h>
  40. +extern int PAM_NONNULL((1,2))
  41. +pam_modutil_check_user_in_passwd(pam_handle_t *pamh,
  42. + const char *user_name,
  43. + const char *file_name);
  44. +
  45. extern struct passwd * PAM_NONNULL((1,2))
  46. pam_modutil_getpwnam(pam_handle_t *pamh, const char *user);
  47. diff --git a/libpam/libpam.map b/libpam/libpam.map
  48. index c9690a91..3cc7ef35 100644
  49. --- a/libpam/libpam.map
  50. +++ b/libpam/libpam.map
  51. @@ -82,3 +82,8 @@ LIBPAM_1.4 {
  52. global:
  53. pam_start_confdir;
  54. } LIBPAM_1.0;
  55. +
  56. +LIBPAM_MODUTIL_1.4.1 {
  57. + global:
  58. + pam_modutil_check_user_in_passwd;
  59. +} LIBPAM_MODUTIL_1.3.2;
  60. diff --git a/libpam/pam_modutil_check_user_in_passwd.c b/libpam/pam_modutil_check_user_in_passwd.c
  61. new file mode 100644
  62. index 00000000..b998aa25
  63. --- /dev/null
  64. +++ b/libpam/pam_modutil_check_user_in_passwd.c
  65. @@ -0,0 +1,89 @@
  66. +#include "pam_modutil_private.h"
  67. +#include <security/pam_ext.h>
  68. +
  69. +#include <stdio.h>
  70. +#include <syslog.h>
  71. +
  72. +int
  73. +pam_modutil_check_user_in_passwd(pam_handle_t *pamh,
  74. + const char *user_name,
  75. + const char *file_name)
  76. +{
  77. + int rc;
  78. + size_t user_len;
  79. + FILE *fp;
  80. + char line[BUFSIZ];
  81. +
  82. + /* Validate the user name. */
  83. + if ((user_len = strlen(user_name)) == 0) {
  84. + pam_syslog(pamh, LOG_NOTICE, "user name is not valid");
  85. + return PAM_SERVICE_ERR;
  86. + }
  87. +
  88. + if (user_len > sizeof(line) - sizeof(":")) {
  89. + pam_syslog(pamh, LOG_NOTICE, "user name is too long");
  90. + return PAM_SERVICE_ERR;
  91. + }
  92. +
  93. + if (strchr(user_name, ':') != NULL) {
  94. + /*
  95. + * "root:x" is not a local user name even if the passwd file
  96. + * contains a line starting with "root:x:".
  97. + */
  98. + return PAM_PERM_DENIED;
  99. + }
  100. +
  101. + /* Open the passwd file. */
  102. + if (file_name == NULL) {
  103. + file_name = "/etc/passwd";
  104. + }
  105. + if ((fp = fopen(file_name, "r")) == NULL) {
  106. + pam_syslog(pamh, LOG_ERR, "error opening %s: %m", file_name);
  107. + return PAM_SERVICE_ERR;
  108. + }
  109. +
  110. + /*
  111. + * Scan the file using fgets() instead of fgetpwent_r() because
  112. + * the latter is not flexible enough in handling long lines
  113. + * in passwd files.
  114. + */
  115. + rc = PAM_PERM_DENIED;
  116. + while (fgets(line, sizeof(line), fp) != NULL) {
  117. + size_t line_len;
  118. + const char *str;
  119. +
  120. + /*
  121. + * Does this line start with the user name
  122. + * followed by a colon?
  123. + */
  124. + if (strncmp(user_name, line, user_len) == 0 &&
  125. + line[user_len] == ':') {
  126. + rc = PAM_SUCCESS;
  127. + break;
  128. + }
  129. + /* Has a newline been read? */
  130. + line_len = strlen(line);
  131. + if (line_len < sizeof(line) - 1 ||
  132. + line[line_len - 1] == '\n') {
  133. + /* Yes, continue with the next line. */
  134. + continue;
  135. + }
  136. +
  137. + /* No, read till the end of this line first. */
  138. + while ((str = fgets(line, sizeof(line), fp)) != NULL) {
  139. + line_len = strlen(line);
  140. + if (line_len == 0 ||
  141. + line[line_len - 1] == '\n') {
  142. + break;
  143. + }
  144. + }
  145. + if (str == NULL) {
  146. + /* fgets returned NULL, we are done. */
  147. + break;
  148. + }
  149. + /* Continue with the next line. */
  150. + }
  151. +
  152. + fclose(fp);
  153. + return rc;
  154. +}
  155. diff --git a/modules/pam_faillock/pam_faillock.c b/modules/pam_faillock/pam_faillock.c
  156. index f592d0a2..8bca46ca 100644
  157. --- a/modules/pam_faillock/pam_faillock.c
  158. +++ b/modules/pam_faillock/pam_faillock.c
  159. @@ -348,42 +348,7 @@ set_conf_opt(pam_handle_t *pamh, struct options *opts, const char *name, const c
  160. static int
  161. check_local_user (pam_handle_t *pamh, const char *user)
  162. {
  163. - struct passwd pw, *pwp;
  164. - char buf[16384];
  165. - int found = 0;
  166. - FILE *fp;
  167. - int errn;
  168. -
  169. - fp = fopen(PATH_PASSWD, "r");
  170. - if (fp == NULL) {
  171. - pam_syslog(pamh, LOG_ERR, "unable to open %s: %m",
  172. - PATH_PASSWD);
  173. - return -1;
  174. - }
  175. -
  176. - for (;;) {
  177. - errn = fgetpwent_r(fp, &pw, buf, sizeof (buf), &pwp);
  178. - if (errn == ERANGE) {
  179. - pam_syslog(pamh, LOG_WARNING, "%s contains very long lines; corrupted?",
  180. - PATH_PASSWD);
  181. - break;
  182. - }
  183. - if (errn != 0)
  184. - break;
  185. - if (strcmp(pwp->pw_name, user) == 0) {
  186. - found = 1;
  187. - break;
  188. - }
  189. - }
  190. -
  191. - fclose (fp);
  192. -
  193. - if (errn != 0 && errn != ENOENT) {
  194. - pam_syslog(pamh, LOG_ERR, "unable to enumerate local accounts: %m");
  195. - return -1;
  196. - } else {
  197. - return found;
  198. - }
  199. + return pam_modutil_check_user_in_passwd(pamh, user, NULL);
  200. }
  201. static int
  202. diff --git a/modules/pam_localuser/pam_localuser.c b/modules/pam_localuser/pam_localuser.c
  203. index cb507524..a9f2233c 100644
  204. --- a/modules/pam_localuser/pam_localuser.c
  205. +++ b/modules/pam_localuser/pam_localuser.c
  206. @@ -45,92 +45,10 @@
  207. #include <unistd.h>
  208. #include <security/pam_modules.h>
  209. +#include <security/pam_modutil.h>
  210. #include <security/pam_ext.h>
  211. #include "pam_inline.h"
  212. -static int
  213. -check_user_in_passwd(pam_handle_t *pamh, const char *user_name,
  214. - const char *file_name)
  215. -{
  216. - int rc;
  217. - size_t user_len;
  218. - FILE *fp;
  219. - char line[BUFSIZ];
  220. -
  221. - /* Validate the user name. */
  222. - if ((user_len = strlen(user_name)) == 0) {
  223. - pam_syslog(pamh, LOG_NOTICE, "user name is not valid");
  224. - return PAM_SERVICE_ERR;
  225. - }
  226. -
  227. - if (user_len > sizeof(line) - sizeof(":")) {
  228. - pam_syslog(pamh, LOG_NOTICE, "user name is too long");
  229. - return PAM_SERVICE_ERR;
  230. - }
  231. -
  232. - if (strchr(user_name, ':') != NULL) {
  233. - /*
  234. - * "root:x" is not a local user name even if the passwd file
  235. - * contains a line starting with "root:x:".
  236. - */
  237. - return PAM_PERM_DENIED;
  238. - }
  239. -
  240. - /* Open the passwd file. */
  241. - if (file_name == NULL) {
  242. - file_name = "/etc/passwd";
  243. - }
  244. - if ((fp = fopen(file_name, "r")) == NULL) {
  245. - pam_syslog(pamh, LOG_ERR, "error opening %s: %m", file_name);
  246. - return PAM_SERVICE_ERR;
  247. - }
  248. -
  249. - /*
  250. - * Scan the file using fgets() instead of fgetpwent_r() because
  251. - * the latter is not flexible enough in handling long lines
  252. - * in passwd files.
  253. - */
  254. - rc = PAM_PERM_DENIED;
  255. - while (fgets(line, sizeof(line), fp) != NULL) {
  256. - size_t line_len;
  257. - const char *str;
  258. -
  259. - /*
  260. - * Does this line start with the user name
  261. - * followed by a colon?
  262. - */
  263. - if (strncmp(user_name, line, user_len) == 0 &&
  264. - line[user_len] == ':') {
  265. - rc = PAM_SUCCESS;
  266. - break;
  267. - }
  268. - /* Has a newline been read? */
  269. - line_len = strlen(line);
  270. - if (line_len < sizeof(line) - 1 ||
  271. - line[line_len - 1] == '\n') {
  272. - /* Yes, continue with the next line. */
  273. - continue;
  274. - }
  275. -
  276. - /* No, read till the end of this line first. */
  277. - while ((str = fgets(line, sizeof(line), fp)) != NULL) {
  278. - line_len = strlen(line);
  279. - if (line_len == 0 ||
  280. - line[line_len - 1] == '\n') {
  281. - break;
  282. - }
  283. - }
  284. - if (str == NULL) {
  285. - /* fgets returned NULL, we are done. */
  286. - break;
  287. - }
  288. - /* Continue with the next line. */
  289. - }
  290. -
  291. - fclose(fp);
  292. - return rc;
  293. -}
  294. -
  295. int
  296. pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
  297. int argc, const char **argv)
  298. @@ -173,7 +91,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
  299. return rc == PAM_CONV_AGAIN ? PAM_INCOMPLETE : rc;
  300. }
  301. - return check_user_in_passwd(pamh, user_name, file_name);
  302. + return pam_modutil_check_user_in_passwd(pamh, user_name, file_name);
  303. }
  304. int
  305. --
  306. 2.26.2