[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2] use thread-safe getpwuid_r and getgrgid_r
From: |
Pavel Simovec |
Subject: |
[PATCH v2] use thread-safe getpwuid_r and getgrgid_r |
Date: |
Thu, 25 Jan 2024 10:05:34 +0100 |
---
include/misc.h | 8 +++
libacl/__acl_to_any_text.c | 48 +++++------------
libmisc/Makemodule.am | 1 +
libmisc/uid_gid_lookup.c | 12 ++---
libmisc/user_group.c | 107 +++++++++++++++++++++++++++++++++++++
tools/Makemodule.am | 4 +-
tools/getfacl.c | 28 +++++-----
tools/user_group.c | 60 ---------------------
tools/user_group.h | 30 -----------
9 files changed, 152 insertions(+), 146 deletions(-)
create mode 100644 libmisc/user_group.c
delete mode 100644 tools/user_group.c
delete mode 100644 tools/user_group.h
diff --git a/include/misc.h b/include/misc.h
index 52cfec4..5dd99a6 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -18,6 +18,8 @@
#ifndef __MISC_H
#define __MISC_H
+#include <grp.h>
+#include <pwd.h>
#include <stdio.h>
#include <sys/types.h>
@@ -28,6 +30,12 @@
# define hidden /* hidden */
#endif
+
+char *__acl_user_name(uid_t uid, int numeric);
+char *__acl_group_name(gid_t uid, int numeric);
+
+
+hidden char *__acl_grow_buffer(char **buffer, size_t *bufsize, int type);
hidden int __acl_high_water_alloc(void **buf, size_t *bufsize, size_t newsize);
hidden const char *__acl_quote(const char *str, const char *quote_chars);
diff --git a/libacl/__acl_to_any_text.c b/libacl/__acl_to_any_text.c
index a1555ea..8a35645 100644
--- a/libacl/__acl_to_any_text.c
+++ b/libacl/__acl_to_any_text.c
@@ -31,8 +31,6 @@ static ssize_t acl_entry_to_any_str(const acl_entry_t
entry_d, char *text_p,
ssize_t size, const acl_entry_t mask_d,
const char *prefix, int options);
static ssize_t snprint_uint(char *text_p, ssize_t size, unsigned int i);
-static const char *user_name(uid_t uid);
-static const char *group_name(gid_t uid);
char *
__acl_to_any_text(acl_t acl, ssize_t *len_p, const char *prefix,
@@ -132,6 +130,8 @@ acl_entry_to_any_str(const acl_entry_t entry_d, char
*text_p, ssize_t size,
acl_tag_t type;
ssize_t x;
const char *orig_text_p = text_p, *str;
+ char *gn = NULL;
+ char *un = NULL;
if (!entry_obj_p)
return -1;
if (mask_d) {
@@ -155,11 +155,12 @@ acl_entry_to_any_str(const acl_entry_t entry_d, char
*text_p, ssize_t size,
case ACL_USER: /* additional user */
ABBREV("user:", 5);
if (type == ACL_USER) {
- if (options & TEXT_NUMERIC_IDS)
+ if (options & TEXT_NUMERIC_IDS) {
str = NULL;
- else
- str = __acl_quote(user_name(
- entry_obj_p->eid.qid), ":,
\t\n\r");
+ } else {
+ un =
__acl_user_name(entry_obj_p->eid.qid, 0);
+ str = __acl_quote(un, ":, \t\n\r");
+ }
if (str != NULL) {
strncpy(text_p, str, size);
ADVANCE(strlen(str));
@@ -178,11 +179,12 @@ acl_entry_to_any_str(const acl_entry_t entry_d, char
*text_p, ssize_t size,
case ACL_GROUP: /* additional group */
ABBREV("group:", 6);
if (type == ACL_GROUP) {
- if (options & TEXT_NUMERIC_IDS)
+ if (options & TEXT_NUMERIC_IDS) {
str = NULL;
- else
- str = __acl_quote(group_name(
- entry_obj_p->eid.qid), ":,
\t\n\r");
+ } else {
+ gn =
__acl_group_name(entry_obj_p->eid.qid, 0);
+ str = __acl_quote(gn, ":, \t\n\r");
+ }
if (str != NULL) {
strncpy(text_p, str, size);
ADVANCE(strlen(str));
@@ -217,6 +219,8 @@ acl_entry_to_any_str(const acl_entry_t entry_d, char
*text_p, ssize_t size,
default:
return 0;
}
+ free(gn);
+ free(un);
switch ((size >= 3) ? 3 : size) {
case 3:
@@ -323,27 +327,3 @@ snprint_uint(char *text_p, ssize_t size, unsigned int i)
return digits;
}
-
-static const char *
-user_name(uid_t uid)
-{
- struct passwd *passwd = getpwuid(uid);
-
- if (passwd != NULL)
- return passwd->pw_name;
- else
- return NULL;
-}
-
-
-static const char *
-group_name(gid_t gid)
-{
- struct group *group = getgrgid(gid);
-
- if (group != NULL)
- return group->gr_name;
- else
- return NULL;
-}
-
diff --git a/libmisc/Makemodule.am b/libmisc/Makemodule.am
index 2bb7bf0..273222f 100644
--- a/libmisc/Makemodule.am
+++ b/libmisc/Makemodule.am
@@ -6,4 +6,5 @@ libmisc_la_SOURCES = \
libmisc/next_line.c \
libmisc/quote.c \
libmisc/unquote.c \
+ libmisc/user_group.c \
libmisc/walk_tree.c
diff --git a/libmisc/uid_gid_lookup.c b/libmisc/uid_gid_lookup.c
index 6746afd..511c6c9 100644
--- a/libmisc/uid_gid_lookup.c
+++ b/libmisc/uid_gid_lookup.c
@@ -20,10 +20,10 @@
#include "config.h"
#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
#include <stdlib.h>
#include <string.h>
-#include <pwd.h>
-#include <grp.h>
#include <unistd.h>
#include "libacl.h"
#include "misc.h"
@@ -47,8 +47,8 @@ get_id(const char *token, id_t *id_p)
return 0;
}
-static char *
-grow_buffer(char **buffer, size_t *bufsize, int type)
+char *
+__acl_grow_buffer(char **buffer, size_t *bufsize, int type)
{
long size = *bufsize;
char *buf;
@@ -80,7 +80,7 @@ get_uid(const char *token, uid_t *uid_p)
return 0;
for(;;) {
- if(!grow_buffer(&buffer, &bufsize, _SC_GETPW_R_SIZE_MAX))
+ if(!__acl_grow_buffer(&buffer, &bufsize, _SC_GETPW_R_SIZE_MAX))
break;
err = getpwnam_r(token, &passwd, buffer, bufsize, &result);
@@ -108,7 +108,7 @@ get_gid(const char *token, gid_t *gid_p)
return 0;
for(;;) {
- if(!grow_buffer(&buffer, &bufsize, _SC_GETGR_R_SIZE_MAX))
+ if(!__acl_grow_buffer(&buffer, &bufsize, _SC_GETGR_R_SIZE_MAX))
break;
err = getgrnam_r(token, &group, buffer, bufsize, &result);
diff --git a/libmisc/user_group.c b/libmisc/user_group.c
new file mode 100644
index 0000000..ae3ada7
--- /dev/null
+++ b/libmisc/user_group.c
@@ -0,0 +1,107 @@
+/*
+ File: user_group.c
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <andreas.gruenbacher@gmail.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <grp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "misc.h"
+
+
+char *__acl_user_name(uid_t uid, int numeric)
+{
+ char uid_str[22];
+ struct passwd info, *result = NULL;
+ char *tmpbuf = NULL, *user_name;
+ size_t tmplen = 0;
+ int ret, err;
+
+ if (numeric) {
+ ret = snprintf(uid_str, sizeof(uid_str), "%ld", (long)uid);
+ return strdup(ret < 1 || (size_t)ret >= sizeof(uid_str) ? "?" :
uid_str);
+ }
+
+ for(;;) {
+ if (!__acl_grow_buffer(&tmpbuf, &tmplen, _SC_GETPW_R_SIZE_MAX)) {
+ return NULL;
+ }
+
+ err = getpwuid_r(uid, &info, tmpbuf, tmplen, &result);
+ if (result) {
+ user_name = strdup(info.pw_name);
+ break;
+ }
+ if (err == 0) {
+ err = asprintf(&user_name, "%ld", (long)uid);
+ break;
+ }
+ if (err != ERANGE) {
+ break;
+ }
+ }
+
+ free(tmpbuf);
+ return user_name;
+}
+
+
+char *__acl_group_name(gid_t gid, int numeric)
+{
+ char gid_str[22];
+ struct group info, *result = NULL;
+ char *tmpbuf = NULL, *group_name;
+ size_t tmplen = 0;
+ int ret, err;
+
+ if (numeric) {
+ ret = snprintf(gid_str, sizeof(gid_str), "%ld", (long)gid);
+ return strdup(ret < 1 || (size_t)ret >= sizeof(gid_str) ? "?" :
gid_str);
+ }
+
+ for(;;) {
+ if(!__acl_grow_buffer(&tmpbuf, &tmplen, _SC_GETGR_R_SIZE_MAX)) {
+ return NULL;
+ }
+
+ err = getgrgid_r(gid, &info, tmpbuf, tmplen, &result);
+ if (result) {
+ group_name = strdup(info.gr_name);
+ break;
+ }
+ if (err == 0) {
+ err = asprintf(&group_name, "%ld", (long)gid);
+ break;
+ }
+ if (err != ERANGE) {
+ break;
+ }
+ }
+
+ free(tmpbuf);
+ return group_name;
+}
+
diff --git a/tools/Makemodule.am b/tools/Makemodule.am
index 5475234..5765c42 100644
--- a/tools/Makemodule.am
+++ b/tools/Makemodule.am
@@ -6,9 +6,7 @@ chacl_LDADD = $(tools_ldadd)
bin_PROGRAMS += getfacl
getfacl_SOURCES = \
- tools/getfacl.c \
- tools/user_group.c \
- tools/user_group.h
+ tools/getfacl.c
getfacl_LDADD = $(tools_ldadd)
bin_PROGRAMS += setfacl
diff --git a/tools/getfacl.c b/tools/getfacl.c
index 5a45c04..0f2abcb 100644
--- a/tools/getfacl.c
+++ b/tools/getfacl.c
@@ -36,7 +36,6 @@
#include <libgen.h>
#include <getopt.h>
#include "misc.h"
-#include "user_group.h"
#include "walk_tree.h"
#define POSIXLY_CORRECT_STR "POSIXLY_CORRECT"
@@ -127,37 +126,38 @@ struct name_list *get_list(const struct stat *st, acl_t
acl)
while (ret > 0) {
acl_tag_t e_type;
id_t *id_p;
- const char *name = "";
+ char *name = "";
int len;
acl_get_tag_type(ent, &e_type);
switch(e_type) {
case ACL_USER_OBJ:
- name = user_name(st->st_uid, opt_numeric);
+ name = __acl_user_name(st->st_uid, opt_numeric);
break;
case ACL_USER:
id_p = acl_get_qualifier(ent);
if (id_p != NULL) {
- name = user_name(*id_p, opt_numeric);
+ name = __acl_user_name(*id_p,
opt_numeric);
acl_free(id_p);
}
break;
case ACL_GROUP_OBJ:
- name = group_name(st->st_gid, opt_numeric);
+ name = __acl_group_name(st->st_gid,
opt_numeric);
break;
case ACL_GROUP:
id_p = acl_get_qualifier(ent);
if (id_p != NULL) {
- name = group_name(*id_p, opt_numeric);
+ name = __acl_group_name(*id_p,
opt_numeric);
acl_free(id_p);
}
break;
}
- name = xquote(name, "\t\n\r");
- len = strlen(name);
+ const char *qname = xquote(name, "\t\n\r");
+ free(name);
+ len = strlen(qname);
if (last == NULL) {
first = last = (struct name_list *)
malloc(sizeof(struct name_list) + len + 1);
@@ -171,7 +171,7 @@ struct name_list *get_list(const struct stat *st, acl_t acl)
return NULL;
}
last->next = NULL;
- strcpy(last->name, name);
+ strcpy(last->name, qname);
ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &ent);
}
@@ -515,10 +515,12 @@ int do_print(const char *path_p, const struct stat *st,
int walk_flags, void *un
} else {
if (opt_comments) {
printf("# file: %s\n", xquote(path_p, "\n\r"));
- printf("# owner: %s\n",
- xquote(user_name(st->st_uid, opt_numeric), "
\t\n\r"));
- printf("# group: %s\n",
- xquote(group_name(st->st_gid, opt_numeric), "
\t\n\r"));
+ char *un = __acl_user_name(st->st_uid, opt_numeric);
+ printf("# owner: %s\n", xquote(un, " \t\n\r"));
+ free(un);
+ char *gn = __acl_group_name(st->st_gid, opt_numeric);
+ printf("# group: %s\n", xquote(gn, " \t\n\r"));
+ free(gn);
if ((st->st_mode & (S_ISVTX | S_ISUID | S_ISGID)) &&
!posixly_correct)
printf("# flags: %s\n", flagstr(st->st_mode));
}
diff --git a/tools/user_group.c b/tools/user_group.c
deleted file mode 100644
index bcfb600..0000000
--- a/tools/user_group.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- File: user_group.c
- (Linux Access Control List Management)
-
- Copyright (C) 1999, 2000
- Andreas Gruenbacher, <andreas.gruenbacher@gmail.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- USA.
-*/
-
-#include "config.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include "user_group.h"
-
-
-const char *
-user_name(uid_t uid, int numeric)
-{
- struct passwd *passwd = numeric ? NULL : getpwuid(uid);
- static char uid_str[22];
- int ret;
-
- if (passwd != NULL)
- return passwd->pw_name;
- ret = snprintf(uid_str, sizeof(uid_str), "%ld", (long)uid);
- if (ret < 1 || (size_t)ret >= sizeof(uid_str))
- return "?";
- return uid_str;
-}
-
-
-const char *
-group_name(gid_t gid, int numeric)
-{
- struct group *group = numeric ? NULL : getgrgid(gid);
- static char gid_str[22];
- int ret;
-
- if (group != NULL)
- return group->gr_name;
- ret = snprintf(gid_str, sizeof(gid_str), "%ld", (long)gid);
- if (ret < 1 || (size_t)ret >= sizeof(gid_str))
- return "?";
- return gid_str;
-}
-
diff --git a/tools/user_group.h b/tools/user_group.h
deleted file mode 100644
index 03dd0e0..0000000
--- a/tools/user_group.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- File: user_group.h
- (Linux Access Control List Management)
-
- Copyright (C) 1999 by Andreas Gruenbacher
- <a.gruenbacher@computer.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <https://www.gnu.org/licenses/>.
-*/
-
-#include <sys/types.h>
-#include <pwd.h>
-#include <grp.h>
-
-const char *
-user_name(uid_t uid, int numeric);
-const char *
-group_name(gid_t uid, int numeric);
-
--
2.43.0
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH v2] use thread-safe getpwuid_r and getgrgid_r,
Pavel Simovec <=