Mirror of git://git.busybox.net/busybox with our patches on top
Source
xxxxxxxxxx
int FAST_FUNC getspnam_r(const char *name, struct spwd *struct_buf, char *buffer, size_t buflen,
/* vi: set sw=4 ts=4: */
/*
* Copyright (C) 2014 Tito Ragusa <farmatito@tiscali.it>
*
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
/* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY!!
*
* Rewrite of some parts. Main differences are:
*
* 1) the buffer for getpwuid, getgrgid, getpwnam, getgrnam is dynamically
* allocated.
* If ENABLE_FEATURE_CLEAN_UP is set the buffers are freed at program
* exit using the atexit function to make valgrind happy.
* 2) the passwd/group files:
* a) must contain the expected number of fields (as per count of field
* delimiters ":") or we will complain with a error message.
* b) leading and trailing whitespace in fields is stripped.
* c) some fields are not allowed to be empty (e.g. username, uid/gid),
* and in this case NULL is returned and errno is set to EINVAL.
* This behaviour could be easily changed by modifying PW_DEF, GR_DEF,
* SP_DEF strings (uppercase makes a field mandatory).
* d) the string representing uid/gid must be convertible by strtoXX
* functions, or errno is set to EINVAL.
* e) leading and trailing whitespace in group member names is stripped.
* 3) the internal function for getgrouplist uses dynamically allocated buffer.
* 4) at the moment only the functions really used by busybox code are
* implemented, if you need a particular missing function it should be
* easy to write it by using the internal common code.
*/
struct const_passdb {
const char *filename;
char def[7 + 2*ENABLE_USE_BB_SHADOW];
uint8_t off[7 + 2*ENABLE_USE_BB_SHADOW];
uint8_t numfields;
uint8_t size_of;
};
struct passdb {
const char *filename;
char def[7 + 2*ENABLE_USE_BB_SHADOW];
uint8_t off[7 + 2*ENABLE_USE_BB_SHADOW];
uint8_t numfields;
uint8_t size_of;
FILE *fp;
char *malloced;
};
/* Note: for shadow db, def[] will not contain terminating NUL,
* but convert_to_struct() logic detects def[] end by "less than SP?",
* not by "is it NUL?" condition; and off[0] happens to be zero
* for every db anyway, so there _is_ in fact a terminating NUL there.
*/
/* S = string not empty, s = string maybe empty,
* I = uid,gid, l = long maybe empty, m = members,
* r = reserved
*/
static const struct const_passdb const_pw_db = {
_PATH_PASSWD, PW_DEF,
{
offsetof(struct passwd, pw_name), /* 0 S */
offsetof(struct passwd, pw_passwd), /* 1 s */
offsetof(struct passwd, pw_uid), /* 2 I */
offsetof(struct passwd, pw_gid), /* 3 I */
offsetof(struct passwd, pw_gecos), /* 4 s */
offsetof(struct passwd, pw_dir), /* 5 s */
offsetof(struct passwd, pw_shell) /* 6 s */
},
sizeof(PW_DEF)-1, sizeof(struct passwd)
};
static const struct const_passdb const_gr_db = {
_PATH_GROUP, GR_DEF,
{
offsetof(struct group, gr_name), /* 0 S */
offsetof(struct group, gr_passwd), /* 1 s */
offsetof(struct group, gr_gid), /* 2 I */
offsetof(struct group, gr_mem) /* 3 m (char **) */
},
sizeof(GR_DEF)-1, sizeof(struct group)
};
static const struct const_passdb const_sp_db = {
_PATH_SHADOW, SP_DEF,
{
offsetof(struct spwd, sp_namp), /* 0 S Login name */
offsetof(struct spwd, sp_pwdp), /* 1 s Encrypted password */