[LTP] [PATCH 3/7] Add user/group ID lookup helper functions
Martin Doucha
mdoucha@suse.cz
Fri Sep 3 17:48:44 CEST 2021
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
include/tst_safe_macros.h | 6 +++
include/tst_uid.h | 17 +++++++
lib/tst_uid.c | 100 ++++++++++++++++++++++++++++++++++++++
3 files changed, 123 insertions(+)
diff --git a/include/tst_safe_macros.h b/include/tst_safe_macros.h
index 6fd618597..0238a5de7 100644
--- a/include/tst_safe_macros.h
+++ b/include/tst_safe_macros.h
@@ -625,4 +625,10 @@ int safe_sysinfo(const char *file, const int lineno, struct sysinfo *info);
#define SAFE_SYSINFO(info) \
safe_sysinfo(__FILE__, __LINE__, (info))
+struct passwd *safe_getpwent(const char *file, const int lineno);
+#define SAFE_GETPWENT() safe_getpwent(__FILE__, __LINE__)
+
+struct group *safe_getgrent(const char *file, const int lineno);
+#define SAFE_GETGRENT() safe_getgrent(__FILE__, __LINE__)
+
#endif /* SAFE_MACROS_H__ */
diff --git a/include/tst_uid.h b/include/tst_uid.h
index 7135a9cad..a3bacf64a 100644
--- a/include/tst_uid.h
+++ b/include/tst_uid.h
@@ -15,4 +15,21 @@
gid_t tst_get_free_gid_(const char *file, const int lineno, gid_t skip);
#define tst_get_free_gid(skip) tst_get_free_gid_(__FILE__, __LINE__, (skip))
+/*
+ * Get a specific number of unique existing non-root user or group IDs.
+ * Multiple calls will return additional results, if any. Both functions call
+ * SAFE_GETPWENT() and SAFE_GETGRENT() respectively.
+ * Call endpwent()/endgrent() after the last use of these functions.
+ * Call setpwent()/setgrent() to read user/group IDs from the beginning again.
+ */
+int tst_get_uids_(const char *file, const int lineno, unsigned int count,
+ uid_t *buf);
+#define tst_get_uids(count, buf) \
+ tst_get_uids_(__FILE__, __LINE__, (count), (buf))
+
+int tst_get_gids_(const char *file, const int lineno, unsigned int count,
+ gid_t *buf);
+#define tst_get_gids(count, buf) \
+ tst_get_gids_(__FILE__, __LINE__, (count), (buf))
+
#endif /* TST_UID_H_ */
diff --git a/lib/tst_uid.c b/lib/tst_uid.c
index dd719d312..915a5bc34 100644
--- a/lib/tst_uid.c
+++ b/lib/tst_uid.c
@@ -3,8 +3,10 @@
* Copyright (c) 2021 Linux Test Project
*/
+#define _XOPEN_SOURCE 500
#include <sys/types.h>
#include <grp.h>
+#include <pwd.h>
#include <errno.h>
#define TST_NO_DEFAULT_MAIN
@@ -36,3 +38,101 @@ gid_t tst_get_free_gid_(const char *file, const int lineno, gid_t skip)
tst_brk_(file, lineno, TBROK, "No free group ID found");
return (gid_t)-1;
}
+
+struct passwd *safe_getpwent(const char *file, const int lineno)
+{
+ struct passwd *ret;
+
+ errno = 0;
+ ret = getpwent();
+
+ if (!ret) {
+ if (errno) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "getpwent() failed");
+ } else {
+ tst_brk_(file, lineno, TBROK,
+ "getpwent() failed: end of file");
+ }
+ }
+
+ return ret;
+}
+
+struct group *safe_getgrent(const char *file, const int lineno)
+{
+ struct group *ret;
+
+ errno = 0;
+ ret = getgrent();
+
+ if (!ret) {
+ if (errno) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "getgrent() failed");
+ } else {
+ tst_brk_(file, lineno, TBROK,
+ "getgrent() failed: end of file");
+ }
+ }
+
+ return ret;
+}
+
+int tst_get_uids_(const char *file, const int lineno, unsigned int count,
+ uid_t *buf)
+{
+ struct passwd *pw;
+ unsigned int i, j;
+
+ for (i = 0; i < count;) {
+ pw = safe_getpwent(file, lineno);
+
+ if (!pw)
+ return -1;
+
+ if (!pw->pw_uid)
+ continue;
+
+ for (j = 0; j < i; j++) {
+ if (buf[j] == pw->pw_uid)
+ break;
+ }
+
+ if (j < i)
+ continue;
+
+ buf[i++] = pw->pw_uid;
+ }
+
+ return 0;
+}
+
+int tst_get_gids_(const char *file, const int lineno, unsigned int count,
+ gid_t *buf)
+{
+ struct group *gr;
+ unsigned int i, j;
+
+ for (i = 0; i < count;) {
+ gr = safe_getgrent(file, lineno);
+
+ if (!gr)
+ return -1;
+
+ if (!gr->gr_gid)
+ continue;
+
+ for (j = 0; j < i; j++) {
+ if (buf[j] == gr->gr_gid)
+ break;
+ }
+
+ if (j < i)
+ continue;
+
+ buf[i++] = gr->gr_gid;
+ }
+
+ return 0;
+}
--
2.33.0
More information about the ltp
mailing list