/src/dovecot/src/lib/ipwd.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2011-2018 Dovecot authors, see the included COPYING file */ |
2 | | |
3 | | #define _POSIX_PTHREAD_SEMANTICS /* for Solaris */ |
4 | | #include "lib.h" |
5 | | #include "ipwd.h" |
6 | | |
7 | | #include <unistd.h> |
8 | | |
9 | 0 | #define PWBUF_MIN_SIZE 128 |
10 | 0 | #define GRBUF_MIN_SIZE 128 |
11 | | |
12 | | static void *pwbuf = NULL, *grbuf = NULL; |
13 | | static size_t pwbuf_size, grbuf_size; |
14 | | |
15 | | static void pw_init(void) |
16 | 0 | { |
17 | 0 | size_t old_pwbuf_size = pwbuf_size; |
18 | |
|
19 | 0 | if (pwbuf == NULL || errno == ERANGE) { |
20 | 0 | pwbuf_size = nearest_power(old_pwbuf_size + 1); |
21 | 0 | if (pwbuf_size < PWBUF_MIN_SIZE) |
22 | 0 | pwbuf_size = PWBUF_MIN_SIZE; |
23 | 0 | pwbuf = i_realloc(pwbuf, old_pwbuf_size, pwbuf_size); |
24 | 0 | } |
25 | 0 | } |
26 | | |
27 | | static void gr_init(void) |
28 | 0 | { |
29 | 0 | size_t old_grbuf_size = grbuf_size; |
30 | |
|
31 | 0 | if (grbuf == NULL || errno == ERANGE) { |
32 | 0 | grbuf_size = nearest_power(old_grbuf_size + 1); |
33 | 0 | if (grbuf_size < GRBUF_MIN_SIZE) |
34 | 0 | grbuf_size = GRBUF_MIN_SIZE; |
35 | 0 | grbuf = i_realloc(grbuf, old_grbuf_size, grbuf_size); |
36 | 0 | } |
37 | 0 | } |
38 | | |
39 | | void ipwd_deinit(void) |
40 | 0 | { |
41 | 0 | i_free_and_null(pwbuf); |
42 | 0 | i_free_and_null(grbuf); |
43 | 0 | } |
44 | | |
45 | | int i_getpwnam(const char *name, struct passwd *pwd_r) |
46 | 0 | { |
47 | 0 | struct passwd *result; |
48 | |
|
49 | 0 | errno = 0; |
50 | 0 | do { |
51 | 0 | pw_init(); |
52 | 0 | errno = getpwnam_r(name, pwd_r, pwbuf, pwbuf_size, &result); |
53 | 0 | } while (errno == ERANGE); |
54 | 0 | if (result != NULL) |
55 | 0 | return 1; |
56 | 0 | if (errno == EINVAL) { |
57 | | /* FreeBSD fails here when name="user@domain" */ |
58 | 0 | return 0; |
59 | 0 | } |
60 | 0 | return errno == 0 ? 0 : -1; |
61 | 0 | } |
62 | | |
63 | | int i_getpwuid(uid_t uid, struct passwd *pwd_r) |
64 | 0 | { |
65 | 0 | struct passwd *result; |
66 | |
|
67 | 0 | errno = 0; |
68 | 0 | do { |
69 | 0 | pw_init(); |
70 | 0 | errno = getpwuid_r(uid, pwd_r, pwbuf, pwbuf_size, &result); |
71 | 0 | } while (errno == ERANGE); |
72 | 0 | if (result != NULL) |
73 | 0 | return 1; |
74 | 0 | return errno == 0 ? 0 : -1; |
75 | 0 | } |
76 | | |
77 | | int i_getgrnam(const char *name, struct group *grp_r) |
78 | 0 | { |
79 | 0 | struct group *result; |
80 | |
|
81 | 0 | errno = 0; |
82 | 0 | do { |
83 | 0 | gr_init(); |
84 | 0 | errno = getgrnam_r(name, grp_r, grbuf, grbuf_size, &result); |
85 | 0 | } while (errno == ERANGE); |
86 | 0 | if (result != NULL) |
87 | 0 | return 1; |
88 | 0 | return errno == 0 ? 0 : -1; |
89 | 0 | } |
90 | | |
91 | | int i_getgrgid(gid_t gid, struct group *grp_r) |
92 | 0 | { |
93 | 0 | struct group *result; |
94 | |
|
95 | 0 | errno = 0; |
96 | 0 | do { |
97 | 0 | gr_init(); |
98 | 0 | errno = getgrgid_r(gid, grp_r, grbuf, grbuf_size, &result); |
99 | 0 | } while (errno == ERANGE); |
100 | 0 | if (result != NULL) |
101 | 0 | return 1; |
102 | 0 | return errno == 0 ? 0 : -1; |
103 | 0 | } |