Branch data Line data Source code
1 : : /* GLIB - Library of useful routines for C programming
2 : : *
3 : : * Copyright (C) 2020 Red Hat, Inc.
4 : : *
5 : : * Author: Jakub Jelen <jjelen@redhat.com>
6 : : *
7 : : * SPDX-License-Identifier: LGPL-2.1-or-later
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2.1 of the License, or (at your option) any later version.
13 : : *
14 : : * This library is distributed in the hope that it will be useful,
15 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : * Lesser General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU Lesser General
20 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 : : */
22 : :
23 : : #include <dlfcn.h>
24 : : #include <pwd.h>
25 : : #include <sys/types.h>
26 : : #include <unistd.h>
27 : :
28 : : #ifndef __APPLE__
29 : :
30 : : #define GET_REAL(func) \
31 : : (real_##func = dlsym (RTLD_NEXT, #func))
32 : :
33 : : #define DEFINE_WRAPPER(return_type, func, argument_list) \
34 : : static return_type (* real_##func) argument_list; \
35 : : return_type func argument_list
36 : :
37 : : #else
38 : :
39 : : #define GET_REAL(func) \
40 : : func
41 : :
42 : : /* https://opensource.apple.com/source/dyld/dyld-852.2/include/mach-o/dyld-interposing.h */
43 : : #define DYLD_INTERPOSE(_replacement,_replacee) \
44 : : __attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \
45 : : __attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee };
46 : :
47 : : #define DEFINE_WRAPPER(return_type, func, argument_list) \
48 : : static return_type wrap_##func argument_list; \
49 : : DYLD_INTERPOSE(wrap_##func, func) \
50 : : static return_type wrap_##func argument_list
51 : :
52 : : #endif /* __APPLE__ */
53 : :
54 : : /* This is used in gutils.c used to make sure utility functions
55 : : * handling user information do not crash on bad data (for example
56 : : * caused by getpwuid returning some NULL elements.
57 : : */
58 : :
59 : : #undef getpwuid
60 : :
61 : : static struct passwd my_pw;
62 : :
63 : : DEFINE_WRAPPER (struct passwd *, getpwuid, (uid_t uid))
64 : : {
65 : 0 : struct passwd *pw = GET_REAL (getpwuid) (uid);
66 : 0 : my_pw = *pw;
67 : 0 : my_pw.pw_name = NULL;
68 : 0 : return &my_pw;
69 : : }
70 : :
71 : : DEFINE_WRAPPER (int, getpwnam_r, (const char *name,
72 : : struct passwd *pwd,
73 : : char buf[],
74 : : size_t buflen,
75 : : struct passwd **result))
76 : : {
77 : 0 : int code = GET_REAL (getpwnam_r) (name, pwd, buf, buflen, result);
78 : 0 : pwd->pw_name = NULL;
79 : 0 : return code;
80 : : }
81 : :
82 : : DEFINE_WRAPPER (int, getpwuid_r, (uid_t uid,
83 : : struct passwd *restrict pwd,
84 : : char buf[],
85 : : size_t buflen,
86 : : struct passwd **result))
87 : : {
88 : 1 : int code = GET_REAL (getpwuid_r) (uid, pwd, buf, buflen, result);
89 : 1 : pwd->pw_name = NULL;
90 : 1 : return code;
91 : : }
|