2002-06-05 02:15:46 +05:30
|
|
|
/* vi: set sw=4 ts=4: */
|
|
|
|
/*
|
|
|
|
* adduser - add users to /etc/passwd and /etc/shadow
|
|
|
|
*
|
|
|
|
* Copyright (C) 1999 by Lineo, inc. and John Beppu
|
|
|
|
* Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
|
|
|
|
*
|
2010-08-16 23:44:46 +05:30
|
|
|
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
2002-06-05 02:15:46 +05:30
|
|
|
*/
|
2015-10-19 04:50:36 +05:30
|
|
|
//config:config ADDUSER
|
2017-07-19 01:31:24 +05:30
|
|
|
//config: bool "adduser (15 kb)"
|
2015-10-19 04:50:36 +05:30
|
|
|
//config: default y
|
getopt32: remove applet_long_options
FEATURE_GETOPT_LONG made dependent on LONG_OPTS.
The folloving options are removed, now LONG_OPTS enables long options
for affected applets:
FEATURE_ENV_LONG_OPTIONS FEATURE_EXPAND_LONG_OPTIONS
FEATURE_UNEXPAND_LONG_OPTIONS FEATURE_MKDIR_LONG_OPTIONS
FEATURE_MV_LONG_OPTIONS FEATURE_RMDIR_LONG_OPTIONS
FEATURE_ADDGROUP_LONG_OPTIONS FEATURE_ADDUSER_LONG_OPTIONS
FEATURE_HWCLOCK_LONG_OPTIONS FEATURE_NSENTER_LONG_OPTS
FEATURE_CHCON_LONG_OPTIONS FEATURE_RUNCON_LONG_OPTIONS
They either had a small number of long options, or their long options are
essential.
Example: upstream addgroup and adduser have ONLY longopts,
we should probably go further and get rid
of non-standard short options.
To this end, make addgroup and adduser "select LONG_OPTS".
We had this breakage caused by us even in our own package!
#if ENABLE_LONG_OPTS || !ENABLE_ADDGROUP
/* We try to use --gid, not -g, because "standard" addgroup
* has no short option -g, it has only long --gid.
*/
argv[1] = (char*)"--gid";
#else
/* Breaks if system in fact does NOT use busybox addgroup */
argv[1] = (char*)"-g";
#endif
xargs: its lone longopt no longer depends on DESKTOP, only on LONG_OPTS.
hwclock TODO: get rid of incompatible -t, -l aliases to --systz, --localtime
Shorten help texts by omitting long option when short opt alternative exists.
Reduction of size comes from the fact that store of an immediate
(an address of longopts) to a fixed address (global variable)
is a longer insn than pushing that immediate or passing it in a register.
This effect is CPU-agnostic.
function old new delta
getopt32 1350 22 -1328
vgetopt32 - 1318 +1318
getopt32long - 24 +24
tftpd_main 562 567 +5
scan_recursive 376 380 +4
collect_cpu 545 546 +1
date_main 1096 1095 -1
hostname_main 262 259 -3
uname_main 259 255 -4
setpriv_main 362 358 -4
rmdir_main 191 187 -4
mv_main 562 558 -4
ipcalc_main 548 544 -4
ifenslave_main 641 637 -4
gzip_main 192 188 -4
gunzip_main 77 73 -4
fsfreeze_main 81 77 -4
flock_main 318 314 -4
deluser_main 337 333 -4
cp_main 374 370 -4
chown_main 175 171 -4
applet_long_options 4 - -4
xargs_main 894 889 -5
wget_main 2540 2535 -5
udhcpc_main 2767 2762 -5
touch_main 436 431 -5
tar_main 1014 1009 -5
start_stop_daemon_main 1033 1028 -5
sed_main 682 677 -5
script_main 1082 1077 -5
run_parts_main 330 325 -5
rtcwake_main 459 454 -5
od_main 2169 2164 -5
nl_main 201 196 -5
modprobe_main 773 768 -5
mkdir_main 160 155 -5
ls_main 568 563 -5
install_main 773 768 -5
hwclock_main 411 406 -5
getopt_main 622 617 -5
fstrim_main 256 251 -5
env_main 198 193 -5
dumpleases_main 635 630 -5
dpkg_main 3991 3986 -5
diff_main 1355 1350 -5
cryptpw_main 233 228 -5
cpio_main 593 588 -5
conspy_main 1135 1130 -5
chpasswd_main 313 308 -5
adduser_main 887 882 -5
addgroup_main 416 411 -5
ftpgetput_main 351 345 -6
get_terminal_width_height 242 234 -8
expand_main 690 680 -10
static.expand_longopts 18 - -18
static.unexpand_longopts 27 - -27
mkdir_longopts 28 - -28
env_longopts 30 - -30
static.ifenslave_longopts 34 - -34
mv_longopts 46 - -46
static.rmdir_longopts 48 - -48
packed_usage 31739 31687 -52
------------------------------------------------------------------------------
(add/remove: 2/8 grow/shrink: 3/49 up/down: 1352/-1840) Total: -488 bytes
text data bss dec hex filename
915681 485 6880 923046 e15a6 busybox_old
915428 485 6876 922789 e14a5 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-08-08 20:08:18 +05:30
|
|
|
//config: select LONG_OPTS
|
2015-10-19 04:50:36 +05:30
|
|
|
//config: help
|
2017-07-21 13:20:55 +05:30
|
|
|
//config: Utility for creating a new user account.
|
2015-10-19 04:50:36 +05:30
|
|
|
//config:
|
|
|
|
//config:config FEATURE_CHECK_NAMES
|
|
|
|
//config: bool "Enable sanity check on user/group names in adduser and addgroup"
|
|
|
|
//config: default n
|
|
|
|
//config: depends on ADDUSER || ADDGROUP
|
|
|
|
//config: help
|
2017-07-21 13:20:55 +05:30
|
|
|
//config: Enable sanity check on user and group names in adduser and addgroup.
|
|
|
|
//config: To avoid problems, the user or group name should consist only of
|
|
|
|
//config: letters, digits, underscores, periods, at signs and dashes,
|
|
|
|
//config: and not start with a dash (as defined by IEEE Std 1003.1-2001).
|
|
|
|
//config: For compatibility with Samba machine accounts "$" is also supported
|
|
|
|
//config: at the end of the user or group name.
|
2015-10-19 04:50:36 +05:30
|
|
|
//config:
|
|
|
|
//config:config LAST_ID
|
|
|
|
//config: int "Last valid uid or gid for adduser and addgroup"
|
|
|
|
//config: depends on ADDUSER || ADDGROUP
|
|
|
|
//config: default 60000
|
|
|
|
//config: help
|
2017-07-21 13:20:55 +05:30
|
|
|
//config: Last valid uid or gid for adduser and addgroup
|
2015-10-19 04:50:36 +05:30
|
|
|
//config:
|
|
|
|
//config:config FIRST_SYSTEM_ID
|
|
|
|
//config: int "First valid system uid or gid for adduser and addgroup"
|
|
|
|
//config: depends on ADDUSER || ADDGROUP
|
|
|
|
//config: range 0 LAST_ID
|
|
|
|
//config: default 100
|
|
|
|
//config: help
|
2017-07-21 13:20:55 +05:30
|
|
|
//config: First valid system uid or gid for adduser and addgroup
|
2015-10-19 04:50:36 +05:30
|
|
|
//config:
|
|
|
|
//config:config LAST_SYSTEM_ID
|
|
|
|
//config: int "Last valid system uid or gid for adduser and addgroup"
|
|
|
|
//config: depends on ADDUSER || ADDGROUP
|
|
|
|
//config: range FIRST_SYSTEM_ID LAST_ID
|
|
|
|
//config: default 999
|
|
|
|
//config: help
|
2017-07-21 13:20:55 +05:30
|
|
|
//config: Last valid system uid or gid for adduser and addgroup
|
2015-10-19 04:50:36 +05:30
|
|
|
|
2017-08-07 03:58:15 +05:30
|
|
|
//applet:IF_ADDUSER(APPLET_NOEXEC(adduser, adduser, BB_DIR_USR_SBIN, BB_SUID_DROP, adduser))
|
2015-10-19 04:50:36 +05:30
|
|
|
|
|
|
|
//kbuild:lib-$(CONFIG_ADDUSER) += adduser.o
|
2011-04-02 02:26:30 +05:30
|
|
|
|
|
|
|
//usage:#define adduser_trivial_usage
|
2012-10-08 14:48:08 +05:30
|
|
|
//usage: "[OPTIONS] USER [GROUP]"
|
2011-04-02 02:26:30 +05:30
|
|
|
//usage:#define adduser_full_usage "\n\n"
|
2012-10-08 14:48:08 +05:30
|
|
|
//usage: "Create new user, or add USER to GROUP\n"
|
2011-04-02 02:26:30 +05:30
|
|
|
//usage: "\n -h DIR Home directory"
|
|
|
|
//usage: "\n -g GECOS GECOS field"
|
|
|
|
//usage: "\n -s SHELL Login shell"
|
2017-01-26 23:24:12 +05:30
|
|
|
//usage: "\n -G GRP Group"
|
2011-04-02 02:26:30 +05:30
|
|
|
//usage: "\n -S Create a system user"
|
|
|
|
//usage: "\n -D Don't assign a password"
|
|
|
|
//usage: "\n -H Don't create home directory"
|
|
|
|
//usage: "\n -u UID User id"
|
2015-09-22 00:41:12 +05:30
|
|
|
//usage: "\n -k SKEL Skeleton directory (/etc/skel)"
|
2011-04-02 02:26:30 +05:30
|
|
|
|
2007-05-27 00:30:18 +05:30
|
|
|
#include "libbb.h"
|
2002-06-05 02:15:46 +05:30
|
|
|
|
2009-05-14 03:53:34 +05:30
|
|
|
#if CONFIG_LAST_SYSTEM_ID < CONFIG_FIRST_SYSTEM_ID
|
|
|
|
#error Bad LAST_SYSTEM_ID or FIRST_SYSTEM_ID in .config
|
|
|
|
#endif
|
2014-01-17 13:47:55 +05:30
|
|
|
#if CONFIG_LAST_ID < CONFIG_LAST_SYSTEM_ID
|
|
|
|
#error Bad LAST_ID or LAST_SYSTEM_ID in .config
|
|
|
|
#endif
|
|
|
|
|
2009-05-14 03:53:34 +05:30
|
|
|
|
2009-04-23 03:05:52 +05:30
|
|
|
/* #define OPT_HOME (1 << 0) */ /* unused */
|
|
|
|
/* #define OPT_GECOS (1 << 1) */ /* unused */
|
|
|
|
#define OPT_SHELL (1 << 2)
|
|
|
|
#define OPT_GID (1 << 3)
|
2007-03-13 18:31:14 +05:30
|
|
|
#define OPT_DONT_SET_PASS (1 << 4)
|
2007-10-30 00:55:45 +05:30
|
|
|
#define OPT_SYSTEM_ACCOUNT (1 << 5)
|
2007-03-13 18:31:14 +05:30
|
|
|
#define OPT_DONT_MAKE_HOME (1 << 6)
|
2009-04-23 03:05:52 +05:30
|
|
|
#define OPT_UID (1 << 7)
|
2015-05-26 02:55:19 +05:30
|
|
|
#define OPT_SKEL (1 << 8)
|
2002-06-05 02:15:46 +05:30
|
|
|
|
|
|
|
/* remix */
|
2007-10-30 00:55:45 +05:30
|
|
|
/* recoded such that the uid may be passed in *p */
|
|
|
|
static void passwd_study(struct passwd *p)
|
2002-06-05 02:15:46 +05:30
|
|
|
{
|
2014-01-17 13:47:55 +05:30
|
|
|
int max = CONFIG_LAST_ID;
|
2002-06-05 02:15:46 +05:30
|
|
|
|
2009-04-23 03:05:52 +05:30
|
|
|
if (getpwnam(p->pw_name)) {
|
|
|
|
bb_error_msg_and_die("%s '%s' in use", "user", p->pw_name);
|
|
|
|
/* this format string is reused in adduser and addgroup */
|
2007-10-30 00:55:45 +05:30
|
|
|
}
|
2002-06-05 02:15:46 +05:30
|
|
|
|
2009-04-23 03:05:52 +05:30
|
|
|
if (!(option_mask32 & OPT_UID)) {
|
|
|
|
if (option_mask32 & OPT_SYSTEM_ACCOUNT) {
|
2009-05-14 03:53:34 +05:30
|
|
|
p->pw_uid = CONFIG_FIRST_SYSTEM_ID;
|
|
|
|
max = CONFIG_LAST_SYSTEM_ID;
|
2009-04-23 03:05:52 +05:30
|
|
|
} else {
|
2009-05-14 03:53:34 +05:30
|
|
|
p->pw_uid = CONFIG_LAST_SYSTEM_ID + 1;
|
2009-04-23 03:05:52 +05:30
|
|
|
}
|
|
|
|
}
|
2007-10-30 00:55:45 +05:30
|
|
|
/* check for a free uid (and maybe gid) */
|
2009-01-12 14:50:49 +05:30
|
|
|
while (getpwuid(p->pw_uid) || (p->pw_gid == (gid_t)-1 && getgrgid(p->pw_uid))) {
|
2009-04-23 03:05:52 +05:30
|
|
|
if (option_mask32 & OPT_UID) {
|
|
|
|
/* -u N, cannot pick uid other than N: error */
|
|
|
|
bb_error_msg_and_die("%s '%s' in use", "uid", itoa(p->pw_uid));
|
|
|
|
/* this format string is reused in adduser and addgroup */
|
|
|
|
}
|
|
|
|
if (p->pw_uid == max) {
|
|
|
|
bb_error_msg_and_die("no %cids left", 'u');
|
2011-05-21 23:27:58 +05:30
|
|
|
/* this format string is reused in adduser and addgroup */
|
2009-04-23 03:05:52 +05:30
|
|
|
}
|
2007-10-30 00:55:45 +05:30
|
|
|
p->pw_uid++;
|
2009-01-12 14:50:49 +05:30
|
|
|
}
|
2007-11-04 21:13:26 +05:30
|
|
|
|
2009-01-12 14:50:49 +05:30
|
|
|
if (p->pw_gid == (gid_t)-1) {
|
|
|
|
p->pw_gid = p->pw_uid; /* new gid = uid */
|
2009-04-23 03:05:52 +05:30
|
|
|
if (getgrnam(p->pw_name)) {
|
|
|
|
bb_error_msg_and_die("%s '%s' in use", "group", p->pw_name);
|
|
|
|
/* this format string is reused in adduser and addgroup */
|
|
|
|
}
|
2003-06-22 01:33:07 +05:30
|
|
|
}
|
2002-06-05 02:15:46 +05:30
|
|
|
}
|
|
|
|
|
2012-10-08 14:48:08 +05:30
|
|
|
static int addgroup_wrapper(struct passwd *p, const char *group_name)
|
2002-06-05 02:15:46 +05:30
|
|
|
{
|
2011-05-13 06:49:01 +05:30
|
|
|
char *argv[6];
|
2002-07-17 05:20:05 +05:30
|
|
|
|
2011-02-27 08:33:27 +05:30
|
|
|
argv[0] = (char*)"addgroup";
|
|
|
|
if (group_name) {
|
|
|
|
/* Add user to existing group */
|
2011-05-13 06:49:01 +05:30
|
|
|
argv[1] = (char*)"--";
|
|
|
|
argv[2] = p->pw_name;
|
|
|
|
argv[3] = (char*)group_name;
|
|
|
|
argv[4] = NULL;
|
2011-02-27 08:33:27 +05:30
|
|
|
} else {
|
2011-05-21 23:27:58 +05:30
|
|
|
/* Add user to his own group with the first free gid
|
|
|
|
* found in passwd_study.
|
|
|
|
*/
|
|
|
|
argv[1] = (char*)"--gid";
|
2011-02-27 08:33:27 +05:30
|
|
|
argv[2] = utoa(p->pw_gid);
|
2011-05-13 06:49:01 +05:30
|
|
|
argv[3] = (char*)"--";
|
|
|
|
argv[4] = p->pw_name;
|
|
|
|
argv[5] = NULL;
|
2011-02-27 08:33:27 +05:30
|
|
|
}
|
|
|
|
|
2012-10-08 14:48:08 +05:30
|
|
|
return spawn_and_wait(argv);
|
2002-06-05 02:15:46 +05:30
|
|
|
}
|
|
|
|
|
2011-01-26 03:51:46 +05:30
|
|
|
static void passwd_wrapper(const char *login_name) NORETURN;
|
2002-09-16 11:52:25 +05:30
|
|
|
|
2011-01-26 03:51:46 +05:30
|
|
|
static void passwd_wrapper(const char *login_name)
|
2002-06-05 02:15:46 +05:30
|
|
|
{
|
2011-05-13 06:49:01 +05:30
|
|
|
BB_EXECLP("passwd", "passwd", "--", login_name, NULL);
|
libbb: reduce the overhead of single parameter bb_error_msg() calls
Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by
Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower
overhead call to bb_perror_msg() when only a string was being printed
with no parameters. This saves space for some CPU architectures because
it avoids the overhead of a call to a variadic function. However there
has never been a simple version of bb_error_msg(), and since 2007 many
new calls to bb_perror_msg() have been added that only take a single
parameter and so could have been using bb_simple_perror_message().
This changeset introduces 'simple' versions of bb_info_msg(),
bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and
bb_herror_msg_and_die(), and replaces all calls that only take a
single parameter, or use something like ("%s", arg), with calls to the
corresponding 'simple' version.
Since it is likely that single parameter calls to the variadic functions
may be accidentally reintroduced in the future a new debugging config
option WARN_SIMPLE_MSG has been introduced. This uses some macro magic
which will cause any such calls to generate a warning, but this is
turned off by default to avoid use of the unpleasant macros in normal
circumstances.
This is a large changeset due to the number of calls that have been
replaced. The only files that contain changes other than simple
substitution of function calls are libbb.h, libbb/herror_msg.c,
libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c,
networking/udhcp/common.h and util-linux/mdev.c additonal macros have
been added for logging so that single parameter and multiple parameter
logging variants exist.
The amount of space saved varies considerably by architecture, and was
found to be as follows (for 'defconfig' using GCC 7.4):
Arm: -92 bytes
MIPS: -52 bytes
PPC: -1836 bytes
x86_64: -938 bytes
Note that for the MIPS architecture only an exception had to be made
disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h)
because it made these files larger on MIPS.
Signed-off-by: James Byrne <james.byrne@origamienergy.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 15:05:03 +05:30
|
|
|
bb_simple_error_msg_and_die("can't execute passwd, you must set password manually");
|
2002-06-05 02:15:46 +05:30
|
|
|
}
|
|
|
|
|
getopt32: remove applet_long_options
FEATURE_GETOPT_LONG made dependent on LONG_OPTS.
The folloving options are removed, now LONG_OPTS enables long options
for affected applets:
FEATURE_ENV_LONG_OPTIONS FEATURE_EXPAND_LONG_OPTIONS
FEATURE_UNEXPAND_LONG_OPTIONS FEATURE_MKDIR_LONG_OPTIONS
FEATURE_MV_LONG_OPTIONS FEATURE_RMDIR_LONG_OPTIONS
FEATURE_ADDGROUP_LONG_OPTIONS FEATURE_ADDUSER_LONG_OPTIONS
FEATURE_HWCLOCK_LONG_OPTIONS FEATURE_NSENTER_LONG_OPTS
FEATURE_CHCON_LONG_OPTIONS FEATURE_RUNCON_LONG_OPTIONS
They either had a small number of long options, or their long options are
essential.
Example: upstream addgroup and adduser have ONLY longopts,
we should probably go further and get rid
of non-standard short options.
To this end, make addgroup and adduser "select LONG_OPTS".
We had this breakage caused by us even in our own package!
#if ENABLE_LONG_OPTS || !ENABLE_ADDGROUP
/* We try to use --gid, not -g, because "standard" addgroup
* has no short option -g, it has only long --gid.
*/
argv[1] = (char*)"--gid";
#else
/* Breaks if system in fact does NOT use busybox addgroup */
argv[1] = (char*)"-g";
#endif
xargs: its lone longopt no longer depends on DESKTOP, only on LONG_OPTS.
hwclock TODO: get rid of incompatible -t, -l aliases to --systz, --localtime
Shorten help texts by omitting long option when short opt alternative exists.
Reduction of size comes from the fact that store of an immediate
(an address of longopts) to a fixed address (global variable)
is a longer insn than pushing that immediate or passing it in a register.
This effect is CPU-agnostic.
function old new delta
getopt32 1350 22 -1328
vgetopt32 - 1318 +1318
getopt32long - 24 +24
tftpd_main 562 567 +5
scan_recursive 376 380 +4
collect_cpu 545 546 +1
date_main 1096 1095 -1
hostname_main 262 259 -3
uname_main 259 255 -4
setpriv_main 362 358 -4
rmdir_main 191 187 -4
mv_main 562 558 -4
ipcalc_main 548 544 -4
ifenslave_main 641 637 -4
gzip_main 192 188 -4
gunzip_main 77 73 -4
fsfreeze_main 81 77 -4
flock_main 318 314 -4
deluser_main 337 333 -4
cp_main 374 370 -4
chown_main 175 171 -4
applet_long_options 4 - -4
xargs_main 894 889 -5
wget_main 2540 2535 -5
udhcpc_main 2767 2762 -5
touch_main 436 431 -5
tar_main 1014 1009 -5
start_stop_daemon_main 1033 1028 -5
sed_main 682 677 -5
script_main 1082 1077 -5
run_parts_main 330 325 -5
rtcwake_main 459 454 -5
od_main 2169 2164 -5
nl_main 201 196 -5
modprobe_main 773 768 -5
mkdir_main 160 155 -5
ls_main 568 563 -5
install_main 773 768 -5
hwclock_main 411 406 -5
getopt_main 622 617 -5
fstrim_main 256 251 -5
env_main 198 193 -5
dumpleases_main 635 630 -5
dpkg_main 3991 3986 -5
diff_main 1355 1350 -5
cryptpw_main 233 228 -5
cpio_main 593 588 -5
conspy_main 1135 1130 -5
chpasswd_main 313 308 -5
adduser_main 887 882 -5
addgroup_main 416 411 -5
ftpgetput_main 351 345 -6
get_terminal_width_height 242 234 -8
expand_main 690 680 -10
static.expand_longopts 18 - -18
static.unexpand_longopts 27 - -27
mkdir_longopts 28 - -28
env_longopts 30 - -30
static.ifenslave_longopts 34 - -34
mv_longopts 46 - -46
static.rmdir_longopts 48 - -48
packed_usage 31739 31687 -52
------------------------------------------------------------------------------
(add/remove: 2/8 grow/shrink: 3/49 up/down: 1352/-1840) Total: -488 bytes
text data bss dec hex filename
915681 485 6880 923046 e15a6 busybox_old
915428 485 6876 922789 e14a5 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-08-08 20:08:18 +05:30
|
|
|
//FIXME: upstream adduser has no short options! NOT COMPATIBLE!
|
2008-02-15 20:47:23 +05:30
|
|
|
static const char adduser_longopts[] ALIGN1 =
|
|
|
|
"home\0" Required_argument "h"
|
|
|
|
"gecos\0" Required_argument "g"
|
|
|
|
"shell\0" Required_argument "s"
|
|
|
|
"ingroup\0" Required_argument "G"
|
|
|
|
"disabled-password\0" No_argument "D"
|
|
|
|
"empty-password\0" No_argument "D"
|
|
|
|
"system\0" No_argument "S"
|
|
|
|
"no-create-home\0" No_argument "H"
|
2009-04-23 03:05:52 +05:30
|
|
|
"uid\0" Required_argument "u"
|
2015-05-26 02:55:19 +05:30
|
|
|
"skel\0" Required_argument "k"
|
2008-02-15 20:47:23 +05:30
|
|
|
;
|
|
|
|
|
2007-10-30 00:55:45 +05:30
|
|
|
/*
|
|
|
|
* adduser will take a login_name as its first parameter.
|
|
|
|
* home, shell, gecos:
|
|
|
|
* can be customized via command-line parameters.
|
|
|
|
*/
|
|
|
|
int adduser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
2008-07-05 14:48:54 +05:30
|
|
|
int adduser_main(int argc UNUSED_PARAM, char **argv)
|
2002-06-05 02:15:46 +05:30
|
|
|
{
|
2007-10-30 00:55:45 +05:30
|
|
|
struct passwd pw;
|
|
|
|
const char *usegroup = NULL;
|
2009-04-14 06:21:05 +05:30
|
|
|
char *p;
|
2009-04-23 03:05:52 +05:30
|
|
|
unsigned opts;
|
2014-01-17 13:47:55 +05:30
|
|
|
char *uid;
|
2015-05-26 02:55:19 +05:30
|
|
|
const char *skel = "/etc/skel";
|
2002-06-05 02:15:46 +05:30
|
|
|
|
2007-10-30 00:55:45 +05:30
|
|
|
/* got root? */
|
|
|
|
if (geteuid()) {
|
libbb: reduce the overhead of single parameter bb_error_msg() calls
Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by
Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower
overhead call to bb_perror_msg() when only a string was being printed
with no parameters. This saves space for some CPU architectures because
it avoids the overhead of a call to a variadic function. However there
has never been a simple version of bb_error_msg(), and since 2007 many
new calls to bb_perror_msg() have been added that only take a single
parameter and so could have been using bb_simple_perror_message().
This changeset introduces 'simple' versions of bb_info_msg(),
bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and
bb_herror_msg_and_die(), and replaces all calls that only take a
single parameter, or use something like ("%s", arg), with calls to the
corresponding 'simple' version.
Since it is likely that single parameter calls to the variadic functions
may be accidentally reintroduced in the future a new debugging config
option WARN_SIMPLE_MSG has been introduced. This uses some macro magic
which will cause any such calls to generate a warning, but this is
turned off by default to avoid use of the unpleasant macros in normal
circumstances.
This is a large changeset due to the number of calls that have been
replaced. The only files that contain changes other than simple
substitution of function calls are libbb.h, libbb/herror_msg.c,
libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c,
networking/udhcp/common.h and util-linux/mdev.c additonal macros have
been added for logging so that single parameter and multiple parameter
logging variants exist.
The amount of space saved varies considerably by architecture, and was
found to be as follows (for 'defconfig' using GCC 7.4):
Arm: -92 bytes
MIPS: -52 bytes
PPC: -1836 bytes
x86_64: -938 bytes
Note that for the MIPS architecture only an exception had to be made
disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h)
because it made these files larger on MIPS.
Signed-off-by: James Byrne <james.byrne@origamienergy.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 15:05:03 +05:30
|
|
|
bb_simple_error_msg_and_die(bb_msg_perm_denied_are_you_root);
|
2007-03-07 15:05:43 +05:30
|
|
|
}
|
2002-06-05 02:15:46 +05:30
|
|
|
|
2007-10-30 00:55:45 +05:30
|
|
|
pw.pw_gecos = (char *)"Linux User,,,";
|
2011-03-09 01:30:36 +05:30
|
|
|
/* We assume that newly created users "inherit" root's shell setting */
|
2019-01-12 16:21:58 +05:30
|
|
|
pw.pw_shell = xstrdup(get_shell_name()); /* might come from getpwnam(), need to make a copy */
|
2007-10-30 00:55:45 +05:30
|
|
|
pw.pw_dir = NULL;
|
|
|
|
|
2017-08-09 01:25:02 +05:30
|
|
|
opts = getopt32long(argv, "^"
|
|
|
|
"h:g:s:G:DSHu:k:"
|
|
|
|
/* at least one and at most two non-option args */
|
|
|
|
/* disable interactive passwd for system accounts */
|
|
|
|
"\0" "-1:?2:SD",
|
|
|
|
adduser_longopts,
|
getopt32: remove applet_long_options
FEATURE_GETOPT_LONG made dependent on LONG_OPTS.
The folloving options are removed, now LONG_OPTS enables long options
for affected applets:
FEATURE_ENV_LONG_OPTIONS FEATURE_EXPAND_LONG_OPTIONS
FEATURE_UNEXPAND_LONG_OPTIONS FEATURE_MKDIR_LONG_OPTIONS
FEATURE_MV_LONG_OPTIONS FEATURE_RMDIR_LONG_OPTIONS
FEATURE_ADDGROUP_LONG_OPTIONS FEATURE_ADDUSER_LONG_OPTIONS
FEATURE_HWCLOCK_LONG_OPTIONS FEATURE_NSENTER_LONG_OPTS
FEATURE_CHCON_LONG_OPTIONS FEATURE_RUNCON_LONG_OPTIONS
They either had a small number of long options, or their long options are
essential.
Example: upstream addgroup and adduser have ONLY longopts,
we should probably go further and get rid
of non-standard short options.
To this end, make addgroup and adduser "select LONG_OPTS".
We had this breakage caused by us even in our own package!
#if ENABLE_LONG_OPTS || !ENABLE_ADDGROUP
/* We try to use --gid, not -g, because "standard" addgroup
* has no short option -g, it has only long --gid.
*/
argv[1] = (char*)"--gid";
#else
/* Breaks if system in fact does NOT use busybox addgroup */
argv[1] = (char*)"-g";
#endif
xargs: its lone longopt no longer depends on DESKTOP, only on LONG_OPTS.
hwclock TODO: get rid of incompatible -t, -l aliases to --systz, --localtime
Shorten help texts by omitting long option when short opt alternative exists.
Reduction of size comes from the fact that store of an immediate
(an address of longopts) to a fixed address (global variable)
is a longer insn than pushing that immediate or passing it in a register.
This effect is CPU-agnostic.
function old new delta
getopt32 1350 22 -1328
vgetopt32 - 1318 +1318
getopt32long - 24 +24
tftpd_main 562 567 +5
scan_recursive 376 380 +4
collect_cpu 545 546 +1
date_main 1096 1095 -1
hostname_main 262 259 -3
uname_main 259 255 -4
setpriv_main 362 358 -4
rmdir_main 191 187 -4
mv_main 562 558 -4
ipcalc_main 548 544 -4
ifenslave_main 641 637 -4
gzip_main 192 188 -4
gunzip_main 77 73 -4
fsfreeze_main 81 77 -4
flock_main 318 314 -4
deluser_main 337 333 -4
cp_main 374 370 -4
chown_main 175 171 -4
applet_long_options 4 - -4
xargs_main 894 889 -5
wget_main 2540 2535 -5
udhcpc_main 2767 2762 -5
touch_main 436 431 -5
tar_main 1014 1009 -5
start_stop_daemon_main 1033 1028 -5
sed_main 682 677 -5
script_main 1082 1077 -5
run_parts_main 330 325 -5
rtcwake_main 459 454 -5
od_main 2169 2164 -5
nl_main 201 196 -5
modprobe_main 773 768 -5
mkdir_main 160 155 -5
ls_main 568 563 -5
install_main 773 768 -5
hwclock_main 411 406 -5
getopt_main 622 617 -5
fstrim_main 256 251 -5
env_main 198 193 -5
dumpleases_main 635 630 -5
dpkg_main 3991 3986 -5
diff_main 1355 1350 -5
cryptpw_main 233 228 -5
cpio_main 593 588 -5
conspy_main 1135 1130 -5
chpasswd_main 313 308 -5
adduser_main 887 882 -5
addgroup_main 416 411 -5
ftpgetput_main 351 345 -6
get_terminal_width_height 242 234 -8
expand_main 690 680 -10
static.expand_longopts 18 - -18
static.unexpand_longopts 27 - -27
mkdir_longopts 28 - -28
env_longopts 30 - -30
static.ifenslave_longopts 34 - -34
mv_longopts 46 - -46
static.rmdir_longopts 48 - -48
packed_usage 31739 31687 -52
------------------------------------------------------------------------------
(add/remove: 2/8 grow/shrink: 3/49 up/down: 1352/-1840) Total: -488 bytes
text data bss dec hex filename
915681 485 6880 923046 e15a6 busybox_old
915428 485 6876 922789 e14a5 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-08-08 20:08:18 +05:30
|
|
|
&pw.pw_dir, &pw.pw_gecos, &pw.pw_shell,
|
2017-08-09 01:25:02 +05:30
|
|
|
&usegroup, &uid, &skel
|
|
|
|
);
|
2014-01-17 13:47:55 +05:30
|
|
|
if (opts & OPT_UID)
|
|
|
|
pw.pw_uid = xatou_range(uid, 0, CONFIG_LAST_ID);
|
|
|
|
|
2007-10-30 00:55:45 +05:30
|
|
|
argv += optind;
|
2012-10-08 14:48:08 +05:30
|
|
|
pw.pw_name = argv[0];
|
|
|
|
|
|
|
|
if (!opts && argv[1]) {
|
|
|
|
/* if called with two non-option arguments, adduser
|
|
|
|
* will add an existing user to an existing group.
|
|
|
|
*/
|
|
|
|
return addgroup_wrapper(&pw, argv[1]);
|
|
|
|
}
|
2007-10-30 00:55:45 +05:30
|
|
|
|
|
|
|
/* fill in the passwd struct */
|
2008-03-20 04:45:26 +05:30
|
|
|
die_if_bad_username(pw.pw_name);
|
2007-10-30 00:55:45 +05:30
|
|
|
if (!pw.pw_dir) {
|
|
|
|
/* create string for $HOME if not specified already */
|
|
|
|
pw.pw_dir = xasprintf("/home/%s", argv[0]);
|
|
|
|
}
|
|
|
|
pw.pw_passwd = (char *)"x";
|
2009-04-23 03:05:52 +05:30
|
|
|
if (opts & OPT_SYSTEM_ACCOUNT) {
|
|
|
|
if (!usegroup) {
|
|
|
|
usegroup = "nogroup";
|
|
|
|
}
|
|
|
|
if (!(opts & OPT_SHELL)) {
|
|
|
|
pw.pw_shell = (char *) "/bin/false";
|
|
|
|
}
|
|
|
|
}
|
2009-01-12 14:50:49 +05:30
|
|
|
pw.pw_gid = usegroup ? xgroup2gid(usegroup) : -1; /* exits on failure */
|
2007-10-30 00:55:45 +05:30
|
|
|
|
|
|
|
/* make sure everything is kosher and setup uid && maybe gid */
|
|
|
|
passwd_study(&pw);
|
|
|
|
|
2009-04-23 03:05:52 +05:30
|
|
|
p = xasprintf("x:%u:%u:%s:%s:%s",
|
|
|
|
(unsigned) pw.pw_uid, (unsigned) pw.pw_gid,
|
|
|
|
pw.pw_gecos, pw.pw_dir, pw.pw_shell);
|
2009-04-14 06:21:05 +05:30
|
|
|
if (update_passwd(bb_path_passwd_file, pw.pw_name, p, NULL) < 0) {
|
|
|
|
return EXIT_FAILURE;
|
2002-06-05 02:15:46 +05:30
|
|
|
}
|
2009-04-14 06:21:05 +05:30
|
|
|
if (ENABLE_FEATURE_CLEAN_UP)
|
|
|
|
free(p);
|
2006-04-05 00:49:53 +05:30
|
|
|
#if ENABLE_FEATURE_SHADOWPASSWDS
|
2009-07-13 04:45:30 +05:30
|
|
|
/* /etc/shadow fields:
|
|
|
|
* 1. username
|
|
|
|
* 2. encrypted password
|
|
|
|
* 3. last password change (unix date (unix time/24*60*60))
|
|
|
|
* 4. minimum days required between password changes
|
|
|
|
* 5. maximum days password is valid
|
|
|
|
* 6. days before password is to expire that user is warned
|
|
|
|
* 7. days after password expires that account is disabled
|
2009-07-13 04:57:47 +05:30
|
|
|
* 8. unix date when login expires (i.e. when it may no longer be used)
|
2009-07-13 04:45:30 +05:30
|
|
|
*/
|
|
|
|
/* fields: 2 3 4 5 6 78 */
|
|
|
|
p = xasprintf("!:%u:0:99999:7:::", (unsigned)(time(NULL)) / (24*60*60));
|
2009-04-14 15:28:11 +05:30
|
|
|
/* ignore errors: if file is missing we suppose admin doesn't want it */
|
2009-04-14 06:21:05 +05:30
|
|
|
update_passwd(bb_path_shadow_file, pw.pw_name, p, NULL);
|
|
|
|
if (ENABLE_FEATURE_CLEAN_UP)
|
|
|
|
free(p);
|
2002-06-05 02:15:46 +05:30
|
|
|
#endif
|
|
|
|
|
2006-04-05 00:49:53 +05:30
|
|
|
/* add to group */
|
2010-01-10 08:55:05 +05:30
|
|
|
addgroup_wrapper(&pw, usegroup);
|
2006-07-17 00:28:18 +05:30
|
|
|
|
2009-04-14 15:28:11 +05:30
|
|
|
/* clear the umask for this process so it doesn't
|
2007-07-15 04:21:28 +05:30
|
|
|
* screw up the permissions on the mkdir and chown. */
|
2002-06-05 02:15:46 +05:30
|
|
|
umask(0);
|
2009-04-23 03:05:52 +05:30
|
|
|
if (!(opts & OPT_DONT_MAKE_HOME)) {
|
|
|
|
/* set the owner and group so it is owned by the new user,
|
|
|
|
* then fix up the permissions to 2755. Can't do it before
|
|
|
|
* since chown will clear the setgid bit */
|
2010-02-07 02:20:59 +05:30
|
|
|
int mkdir_err = mkdir(pw.pw_dir, 0755);
|
|
|
|
if (mkdir_err == 0) {
|
|
|
|
/* New home. Copy /etc/skel to it */
|
|
|
|
const char *args[] = {
|
2011-05-21 23:27:58 +05:30
|
|
|
"chown",
|
|
|
|
"-R",
|
2010-02-07 02:20:59 +05:30
|
|
|
xasprintf("%u:%u", (int)pw.pw_uid, (int)pw.pw_gid),
|
2011-05-21 23:27:58 +05:30
|
|
|
pw.pw_dir,
|
|
|
|
NULL
|
2010-02-07 02:20:59 +05:30
|
|
|
};
|
|
|
|
/* Be silent on any errors (like: no /etc/skel) */
|
2015-05-26 02:55:19 +05:30
|
|
|
if (!(opts & OPT_SKEL))
|
|
|
|
logmode = LOGMODE_NONE;
|
|
|
|
copy_file(skel, pw.pw_dir, FILEUTILS_RECUR);
|
2010-02-07 02:20:59 +05:30
|
|
|
logmode = LOGMODE_STDIO;
|
|
|
|
chown_main(4, (char**)args);
|
|
|
|
}
|
|
|
|
if ((mkdir_err != 0 && errno != EEXIST)
|
2010-01-10 08:55:05 +05:30
|
|
|
|| chown(pw.pw_dir, pw.pw_uid, pw.pw_gid) != 0
|
|
|
|
|| chmod(pw.pw_dir, 02755) != 0 /* set setgid bit on homedir */
|
2007-11-04 21:13:26 +05:30
|
|
|
) {
|
2007-10-30 00:55:45 +05:30
|
|
|
bb_simple_perror_msg(pw.pw_dir);
|
2006-09-17 21:58:10 +05:30
|
|
|
}
|
2006-04-05 00:49:53 +05:30
|
|
|
}
|
|
|
|
|
2009-04-23 03:05:52 +05:30
|
|
|
if (!(opts & OPT_DONT_SET_PASS)) {
|
2003-06-22 01:33:07 +05:30
|
|
|
/* interactively set passwd */
|
2007-10-30 00:55:45 +05:30
|
|
|
passwd_wrapper(pw.pw_name);
|
2002-06-05 02:15:46 +05:30
|
|
|
}
|
2003-06-22 01:33:07 +05:30
|
|
|
|
2010-02-07 02:20:59 +05:30
|
|
|
return EXIT_SUCCESS;
|
2002-06-05 02:15:46 +05:30
|
|
|
}
|