diff options
-rw-r--r-- | libpwdgrp/pwd_grp.c | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c index 0d8e2bb5c..823884edc 100644 --- a/libpwdgrp/pwd_grp.c +++ b/libpwdgrp/pwd_grp.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* Copyright (C) 2014 Tito Ragusa <farmatito@tiscali.it> | 2 | /* Copyright (C) 2014 Tito Ragusa <farmatito@tiscali.it> |
3 | * | 3 | * |
4 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 4 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
5 | */ | 5 | */ |
@@ -9,38 +9,33 @@ | |||
9 | * Rewrite of some parts. Main differences are: | 9 | * Rewrite of some parts. Main differences are: |
10 | * | 10 | * |
11 | * 1) the buffer for getpwuid, getgrgid, getpwnam, getgrnam is dynamically | 11 | * 1) the buffer for getpwuid, getgrgid, getpwnam, getgrnam is dynamically |
12 | * allocated and reused by later calls. if ERANGE error pops up it is | 12 | * allocated and reused by later calls. |
13 | * reallocated to the size of the longest line found so far in the | ||
14 | * passwd/group files and reused for later calls. | ||
15 | * If ENABLE_FEATURE_CLEAN_UP is set the buffers are freed at program | 13 | * If ENABLE_FEATURE_CLEAN_UP is set the buffers are freed at program |
16 | * exit using the atexit function to make valgrind happy. | 14 | * exit using the atexit function to make valgrind happy. |
17 | * 2) the passwd/group files: | 15 | * 2) the passwd/group files: |
18 | * a) must contain the expected number of fields (as per count of field | 16 | * a) must contain the expected number of fields (as per count of field |
19 | * delimeters ":") or we will complain with a error message. | 17 | * delimeters ":") or we will complain with a error message. |
20 | * b) leading or trailing whitespace in fields is allowed and handled. | 18 | * b) leading or trailing whitespace in fields is stripped. |
21 | * c) some fields are not allowed to be empty (e.g. username, uid/gid, | 19 | * c) some fields are not allowed to be empty (e.g. username, uid/gid, |
22 | * homedir, shell) and in this case NULL is returned and errno is | 20 | * homedir, shell) and in this case NULL is returned and errno is |
23 | * set to EINVAL. This behaviour could be easily changed by | 21 | * set to EINVAL. This behaviour could be easily changed by |
24 | * modifying PW_DEF, GR_DEF, SP_DEF strings (uppercase | 22 | * modifying PW_DEF, GR_DEF, SP_DEF strings (uppercase |
25 | * makes a field mandatory). | 23 | * makes a field mandatory). |
26 | * d) the string representing uid/gid must be convertible by strtoXX | 24 | * d) the string representing uid/gid must be convertible by strtoXX |
27 | * functions or NULL is returned and errno is set to EINVAL. | 25 | * functions, or errno is set to EINVAL. |
28 | * e) leading or trailing whitespaces in member names and empty members | 26 | * e) leading or trailing whitespace in group member names are stripped. |
29 | * are allowed and handled. | 27 | * 3) the internal function for getgrouplist uses dynamically allocated buffer. |
30 | * 3) the internal function for getgrouplist uses a dynamically allocated | 28 | * 4) at the moment only the functions really used by busybox code are |
31 | * buffer and retries with a bigger one in case it is too small; | ||
32 | * 4) the _r functions use the user supplied buffers that are never reallocated | ||
33 | * but use mostly the same common code as the other functions. | ||
34 | * 5) at the moment only the functions really used by busybox code are | ||
35 | * implemented, if you need a particular missing function it should be | 29 | * implemented, if you need a particular missing function it should be |
36 | * easy to write it by using the internal common code. | 30 | * easy to write it by using the internal common code. |
37 | */ | 31 | */ |
38 | 32 | ||
39 | #include "libbb.h" | 33 | #include "libbb.h" |
40 | 34 | ||
41 | /* S = string not empty, s = string maybe empty, */ | 35 | /* S = string not empty, s = string maybe empty, |
42 | /* I = uid,gid, l = long maybe empty, m = members,*/ | 36 | * I = uid,gid, l = long maybe empty, m = members, |
43 | /* r = reserved */ | 37 | * r = reserved |
38 | */ | ||
44 | #define PW_DEF "SsIIsSS" | 39 | #define PW_DEF "SsIIsSS" |
45 | #define GR_DEF "SsIm" | 40 | #define GR_DEF "SsIm" |
46 | #define SP_DEF "Ssllllllr" | 41 | #define SP_DEF "Ssllllllr" |
@@ -99,7 +94,8 @@ static const struct const_passdb const_sp_db = { _PATH_SHADOW, sp_off, SP_DEF, s | |||
99 | 94 | ||
100 | /* We avoid having big global data. */ | 95 | /* We avoid having big global data. */ |
101 | struct statics { | 96 | struct statics { |
102 | /* It's ok to use one buffer for getpwuid and getpwnam. Manpage says: | 97 | /* It's ok to use same buffer (db[0].malloced) for getpwuid and getpwnam. |
98 | * Manpage says: | ||
103 | * "The return value may point to a static area, and may be overwritten | 99 | * "The return value may point to a static area, and may be overwritten |
104 | * by subsequent calls to getpwent(), getpwnam(), or getpwuid()." | 100 | * by subsequent calls to getpwent(), getpwnam(), or getpwuid()." |
105 | */ | 101 | */ |
@@ -124,14 +120,12 @@ static struct statics *get_S(void) | |||
124 | return ptr_to_statics; | 120 | return ptr_to_statics; |
125 | } | 121 | } |
126 | 122 | ||
127 | /**********************************************************************/ | 123 | /* Internal functions */ |
128 | /* Internal functions */ | ||
129 | /**********************************************************************/ | ||
130 | 124 | ||
131 | /* Divide the passwd/group/shadow record in fields | 125 | /* Divide the passwd/group/shadow record in fields |
132 | * by substituting the given delimeter | 126 | * by substituting the given delimeter |
133 | * e.g. ':' or ',' with '\0'. | 127 | * e.g. ':' or ',' with '\0'. |
134 | * Returns the number of fields found. | 128 | * Returns the number of fields found. |
135 | * Strips leading and trailing whitespace in fields. | 129 | * Strips leading and trailing whitespace in fields. |
136 | */ | 130 | */ |
137 | static int tokenize(char *buffer, int ch) | 131 | static int tokenize(char *buffer, int ch) |
@@ -328,7 +322,7 @@ int FAST_FUNC getpwnam_r(const char *name, struct passwd *struct_buf, char *buff | |||
328 | } | 322 | } |
329 | #if ENABLE_USE_BB_SHADOW | 323 | #if ENABLE_USE_BB_SHADOW |
330 | int FAST_FUNC getspnam_r(const char *name, struct spwd *struct_buf, char *buffer, size_t buflen, | 324 | int FAST_FUNC getspnam_r(const char *name, struct spwd *struct_buf, char *buffer, size_t buflen, |
331 | struct spwd **result) | 325 | struct spwd **result) |
332 | { | 326 | { |
333 | *result = struct_buf; | 327 | *result = struct_buf; |
334 | return getXXnam_r(name, (2 << 2) + 0, buffer, buflen, result); | 328 | return getXXnam_r(name, (2 << 2) + 0, buffer, buflen, result); |
@@ -461,7 +455,7 @@ static gid_t* FAST_FUNC getgrouplist_internal(int *ngroups_ptr, | |||
461 | get_S(); | 455 | get_S(); |
462 | 456 | ||
463 | /* We alloc space for 8 gids at a time. */ | 457 | /* We alloc space for 8 gids at a time. */ |
464 | group_list = xmalloc(8 * sizeof(group_list[0])); | 458 | group_list = xzalloc(8 * sizeof(group_list[0])); |
465 | group_list[0] = gid; | 459 | group_list[0] = gid; |
466 | ngroups = 1; | 460 | ngroups = 1; |
467 | 461 | ||