From: Jaroslav Jindrak Date: Fri, 21 Apr 2023 18:50:41 +0000 (+0200) Subject: passwd: Respect --prefix/-P options X-Git-Tag: 4.14.0-rc1~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=43e60eb681513adc90fbbec67fd23091a46352fe;p=thirdparty%2Fshadow.git passwd: Respect --prefix/-P options Add prefix_getpwnam_r() and xprefix_getpwnam() and make passwd use prefix-aware functions when handling the database. --- diff --git a/lib/prototypes.h b/lib/prototypes.h index 83014202e..7d9299b0c 100644 --- a/lib/prototypes.h +++ b/lib/prototypes.h @@ -326,6 +326,8 @@ extern struct group *prefix_getgrnam(const char *name); extern struct group *prefix_getgrgid(gid_t gid); extern struct passwd *prefix_getpwuid(uid_t uid); extern struct passwd *prefix_getpwnam(const char* name); +extern int prefix_getpwnam_r(const char* name, struct passwd* pwd, + char* buf, size_t buflen, struct passwd** result); extern struct spwd *prefix_getspnam(const char* name); extern struct group *prefix_getgr_nam_gid(const char *grname); extern void prefix_setpwent(void); @@ -481,6 +483,8 @@ extern bool valid (const char *, const struct passwd *); /* xgetpwnam.c */ extern /*@null@*/ /*@only@*/struct passwd *xgetpwnam (const char *); +/* xprefix_getpwnam.c */ +extern /*@null@*/ /*@only@*/struct passwd *xprefix_getpwnam (const char *); /* xgetpwuid.c */ extern /*@null@*/ /*@only@*/struct passwd *xgetpwuid (uid_t); /* xgetgrnam.c */ diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am index 57f98e9ee..6086b45b5 100644 --- a/libmisc/Makefile.am +++ b/libmisc/Makefile.am @@ -75,6 +75,7 @@ libmisc_la_SOURCES = \ utmp.c \ valid.c \ xgetpwnam.c \ + xprefix_getpwnam.c \ xgetpwuid.c \ xgetgrnam.c \ xgetgrgid.c \ diff --git a/libmisc/prefix_flag.c b/libmisc/prefix_flag.c index 4469149d3..60bc5207e 100644 --- a/libmisc/prefix_flag.c +++ b/libmisc/prefix_flag.c @@ -238,6 +238,27 @@ extern struct passwd *prefix_getpwnam(const char* name) return getpwnam(name); } } +extern int prefix_getpwnam_r(const char* name, struct passwd* pwd, + char* buf, size_t buflen, struct passwd** result) +{ + if (passwd_db_file) { + FILE* fg; + int ret = 0; + + fg = fopen(passwd_db_file, "rt"); + if (!fg) + return errno; + while ((ret = fgetpwent_r(fg, pwd, buf, buflen, result)) == 0) { + if (!strcmp(name, pwd->pw_name)) + break; + } + fclose(fg); + return ret; + } + else { + return getpwnam_r(name, pwd, buf, buflen, result); + } +} extern struct spwd *prefix_getspnam(const char* name) { if (spw_db_file) { diff --git a/libmisc/xprefix_getpwnam.c b/libmisc/xprefix_getpwnam.c new file mode 100644 index 000000000..44466290f --- /dev/null +++ b/libmisc/xprefix_getpwnam.c @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * According to the Linux-PAM documentation: + * + * 4.1. Care about standard library calls + * + * In general, writers of authorization-granting applications should + * assume that each module is likely to call any or all 'libc' functions. + * For 'libc' functions that return pointers to static/dynamically + * allocated structures (ie. the library allocates the memory and the + * user is not expected to 'free()' it) any module call to this function + * is likely to corrupt a pointer previously obtained by the application. + * The application programmer should either re-call such a 'libc' + * function after a call to the Linux-PAM library, or copy the structure + * contents to some safe area of memory before passing control to the + * Linux-PAM library. + * + * Two important function classes that fall into this category are + * getpwnam(3) and syslog(3). + * + * This file provides wrapper to the prefix_getpwnam or prefix_getpwnam_r functions. + */ + +#include + +#include "pwio.h" + +#define LOOKUP_TYPE struct passwd +#define FUNCTION_NAME prefix_getpwnam +#define ARG_TYPE const char * +#define ARG_NAME name +#define DUP_FUNCTION __pw_dup +#define HAVE_FUNCTION_R 1 + +#include "xgetXXbyYY.c" + diff --git a/src/passwd.c b/src/passwd.c index 89d173e77..0fbec22c0 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -452,7 +452,7 @@ static void print_status (const struct passwd *pw) char date[80]; struct spwd *sp; - sp = getspnam (pw->pw_name); /* local, no need for xgetspnam */ + sp = prefix_getspnam (pw->pw_name); /* local, no need for xprefix_getspnam */ if (NULL != sp) { date_to_str (sizeof(date), date, sp->sp_lstchg * SCALE), (void) printf ("%s %s %s %lld %lld %lld %lld\n", @@ -781,7 +781,7 @@ int main (int argc, char **argv) {NULL, 0, NULL, '\0'} }; - while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:Suw:x:", + while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:P:Suw:x:", long_options, NULL)) != -1) { switch (c) { case 'a': @@ -922,11 +922,11 @@ int main (int argc, char **argv) Prog); exit (E_NOPERM); } - setpwent (); - while ( (pw = getpwent ()) != NULL ) { + prefix_setpwent (); + while ( (pw = prefix_getpwent ()) != NULL ) { print_status (pw); } - endpwent (); + prefix_endpwent (); exit (E_SUCCESS); } #if 0 @@ -963,7 +963,7 @@ int main (int argc, char **argv) exit (E_NOPERM); } - pw = xgetpwnam (name); + pw = xprefix_getpwnam (name); if (NULL == pw) { (void) fprintf (stderr, _("%s: user '%s' does not exist\n"), @@ -1007,7 +1007,7 @@ int main (int argc, char **argv) /* * The user name is valid, so let's get the shadow file entry. */ - sp = getspnam (name); /* !USE_PAM, no need for xgetspnam */ + sp = prefix_getspnam (name); /* !USE_PAM, no need for xprefix_getspnam */ if (NULL == sp) { if (errno == EACCES) { (void) fprintf (stderr,