summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/pwd_.h16
-rw-r--r--libbb/lineedit.c13
-rw-r--r--libpwdgrp/pwd_grp.c58
-rw-r--r--loginutils/deluser.c9
4 files changed, 53 insertions, 43 deletions
diff --git a/include/pwd_.h b/include/pwd_.h
index 32b5b36..1734829 100644
--- a/include/pwd_.h
+++ b/include/pwd_.h
@@ -36,7 +36,6 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
#define getpwent bb_internal_getpwent
#define getpwuid bb_internal_getpwuid
#define getpwnam bb_internal_getpwnam
-#define getpwent_r bb_internal_getpwent_r
#define getpwnam_r bb_internal_getpwnam_r
/* All function names below should be remapped by #defines above
@@ -48,10 +47,8 @@ void FAST_FUNC setpwent(void);
/* Close the password-file stream. */
void FAST_FUNC endpwent(void);
-#ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS
/* Read an entry from the password-file stream, opening it if necessary. */
struct passwd* FAST_FUNC getpwent(void);
-#endif
/* Search for an entry with a matching user ID. */
struct passwd* FAST_FUNC getpwuid(uid_t __uid);
@@ -59,18 +56,7 @@ struct passwd* FAST_FUNC getpwuid(uid_t __uid);
/* Search for an entry with a matching username. */
struct passwd* FAST_FUNC getpwnam(const char *__name);
-/* Reentrant versions of some of the functions above.
-
- PLEASE NOTE: the `getpwent_r' function is not (yet) standardized.
- The interface may change in later versions of this library. But
- the interface is designed following the principals used for the
- other reentrant functions so the chances are good this is what the
- POSIX people would choose. */
-
-int FAST_FUNC getpwent_r(struct passwd *__restrict __resultbuf,
- char *__restrict __buffer, size_t __buflen,
- struct passwd **__restrict __result);
-
+/* Reentrant versions of some of the functions above. */
int FAST_FUNC getpwnam_r(const char *__restrict __name,
struct passwd *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 720a495..249b401 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -672,23 +672,20 @@ static char *username_path_completion(char *ud)
*/
static NOINLINE unsigned complete_username(const char *ud)
{
- /* Using _r function to avoid pulling in static buffers */
- char line_buff[256];
- struct passwd pwd;
- struct passwd *result;
+ struct passwd *pw;
unsigned userlen;
ud++; /* skip ~ */
userlen = strlen(ud);
setpwent();
- while (!getpwent_r(&pwd, line_buff, sizeof(line_buff), &result)) {
+ while ((pw = getpwent()) != NULL) {
/* Null usernames should result in all users as possible completions. */
- if (/*!userlen || */ strncmp(ud, pwd.pw_name, userlen) == 0) {
- add_match(xasprintf("~%s/", pwd.pw_name));
+ if (/*!userlen || */ strncmp(ud, pw->pw_name, userlen) == 0) {
+ add_match(xasprintf("~%s/", pw->pw_name));
}
}
- endpwent();
+ endpwent(); /* don't keep password file open */
return 1 + userlen;
}
diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c
index 90647e9..7ec704e 100644
--- a/libpwdgrp/pwd_grp.c
+++ b/libpwdgrp/pwd_grp.c
@@ -336,6 +336,22 @@ static int massage_data_for_r_func(struct passdb *db,
return errno;
}
+static void* massage_data_for_non_r_func(struct passdb *db, char *buf)
+{
+ if (!buf)
+ return NULL;
+
+ free(db->malloced);
+ /* We enlarge buf and move string data up, freeing space
+ * for struct passwd/group/spwd at the beginning. This way,
+ * entire result of getXXnam is in a single malloced block.
+ * This enables easy creation of xmalloc_getpwnam() API.
+ */
+ db->malloced = buf = xrealloc(buf, db->size_of + S.string_size);
+ memmove(buf + db->size_of, buf, S.string_size);
+ return convert_to_struct(db, buf + db->size_of, buf);
+}
+
/****** getXXnam/id_r */
static int FAST_FUNC getXXnam_r(const char *name, uintptr_t db_and_field_pos,
@@ -372,6 +388,7 @@ int FAST_FUNC getspnam_r(const char *name, struct spwd *struct_buf, char *buffer
}
#endif
+#ifdef UNUSED
/****** getXXent_r */
static int FAST_FUNC getXXent_r(uintptr_t db_idx, char *buffer, size_t buflen,
@@ -400,17 +417,39 @@ int FAST_FUNC getpwent_r(struct passwd *struct_buf, char *buffer, size_t buflen,
*result = struct_buf;
return getXXent_r(0, buffer, buflen, result);
}
+#endif
+
+/****** getXXent */
+
+static void* FAST_FUNC getXXent(uintptr_t db_idx)
+{
+ char *buf;
+ struct passdb *db = &get_S()->db[db_idx];
+
+ if (!db->fp) {
+ db->fp = fopen_for_read(db->filename);
+ if (!db->fp) {
+ return NULL;
+ }
+ close_on_exec_on(fileno(db->fp));
+ }
+
+ buf = parse_common(db->fp, db, /*no search key:*/ NULL, -1);
+ return massage_data_for_non_r_func(db, buf);
+}
+
+struct passwd* FAST_FUNC getpwent(void)
+{
+ return getXXent(0);
+}
/****** getXXnam/id */
static void* FAST_FUNC getXXnam(const char *name, unsigned db_and_field_pos)
{
char *buf;
- void *result;
struct passdb *db = &get_S()->db[db_and_field_pos >> 2];
- result = NULL;
-
if (!db->fp) {
db->fp = fopen_for_read(db->filename);
if (!db->fp) {
@@ -420,18 +459,7 @@ static void* FAST_FUNC getXXnam(const char *name, unsigned db_and_field_pos)
}
buf = parse_common(db->fp, db, name, db_and_field_pos & 3);
- if (buf) {
- free(db->malloced);
- /* We enlarge buf and move string data up, freeing space
- * for struct passwd/group/spwd at the beginning. This way,
- * entire result of getXXnam is in a single malloced block.
- * This enables easy creation of xmalloc_getpwnam() API.
- */
- db->malloced = buf = xrealloc(buf, db->size_of + S.string_size);
- memmove(buf + db->size_of, buf, S.string_size);
- result = convert_to_struct(db, buf + db->size_of, buf);
- }
- return result;
+ return massage_data_for_non_r_func(db, buf);
}
struct passwd* FAST_FUNC getpwnam(const char *name)
diff --git a/loginutils/deluser.c b/loginutils/deluser.c
index 2d98ecc..01a9386 100644
--- a/loginutils/deluser.c
+++ b/loginutils/deluser.c
@@ -91,12 +91,11 @@ int deluser_main(int argc, char **argv)
if (!member) {
/* "delgroup GROUP" */
struct passwd *pw;
- struct passwd pwent;
/* Check if the group is in use */
-#define passwd_buf bb_common_bufsiz1
- while (!getpwent_r(&pwent, passwd_buf, sizeof(passwd_buf), &pw)) {
- if (pwent.pw_gid == gr->gr_gid)
- bb_error_msg_and_die("'%s' still has '%s' as their primary group!", pwent.pw_name, name);
+ while ((pw = getpwent()) != NULL) {
+ if (pw->pw_gid == gr->gr_gid)
+ bb_error_msg_and_die("'%s' still has '%s' as their primary group!",
+ pw->pw_name, name);
}
//endpwent();
}