acl-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]