diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-20 21:28:41 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-20 21:28:41 +0000 |
commit | 21d1014b5b91d1a1319273945291b7a9f4717827 (patch) | |
tree | b84eadba35d31f923ef62579652e4e5d76678c38 | |
parent | 2f6ae43b9c74d393a139007377895e8c50b8af9a (diff) | |
download | busybox-w32-21d1014b5b91d1a1319273945291b7a9f4717827.tar.gz busybox-w32-21d1014b5b91d1a1319273945291b7a9f4717827.tar.bz2 busybox-w32-21d1014b5b91d1a1319273945291b7a9f4717827.zip |
chpasswd: new applet by Alexander Shishkin <virtuoso@slind.org>
-rw-r--r-- | include/applets.h | 1 | ||||
-rw-r--r-- | include/libbb.h | 14 | ||||
-rw-r--r-- | include/usage.h | 89 | ||||
-rw-r--r-- | libbb/Kbuild | 3 | ||||
-rw-r--r-- | libbb/crypt_make_salt.c | 9 | ||||
-rw-r--r-- | loginutils/Config.in | 8 | ||||
-rw-r--r-- | loginutils/Kbuild | 1 | ||||
-rw-r--r-- | loginutils/cryptpw.c | 4 | ||||
-rw-r--r-- | loginutils/passwd.c | 121 | ||||
-rw-r--r-- | scripts/defconfig | 1 | ||||
-rwxr-xr-x | scripts/trylink | 15 |
11 files changed, 97 insertions, 169 deletions
diff --git a/include/applets.h b/include/applets.h index 90af4f4c3..a05f74abd 100644 --- a/include/applets.h +++ b/include/applets.h | |||
@@ -89,6 +89,7 @@ USE_CHCON(APPLET(chcon, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | |||
89 | USE_CHGRP(APPLET_NOEXEC(chgrp, chgrp, _BB_DIR_BIN, _BB_SUID_NEVER, chgrp)) | 89 | USE_CHGRP(APPLET_NOEXEC(chgrp, chgrp, _BB_DIR_BIN, _BB_SUID_NEVER, chgrp)) |
90 | USE_CHMOD(APPLET_NOEXEC(chmod, chmod, _BB_DIR_BIN, _BB_SUID_NEVER, chmod)) | 90 | USE_CHMOD(APPLET_NOEXEC(chmod, chmod, _BB_DIR_BIN, _BB_SUID_NEVER, chmod)) |
91 | USE_CHOWN(APPLET_NOEXEC(chown, chown, _BB_DIR_BIN, _BB_SUID_NEVER, chown)) | 91 | USE_CHOWN(APPLET_NOEXEC(chown, chown, _BB_DIR_BIN, _BB_SUID_NEVER, chown)) |
92 | USE_CHPASSWD(APPLET(chpasswd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) | ||
92 | USE_CHPST(APPLET(chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 93 | USE_CHPST(APPLET(chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
93 | USE_CHROOT(APPLET(chroot, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) | 94 | USE_CHROOT(APPLET(chroot, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) |
94 | USE_CHRT(APPLET(chrt, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 95 | USE_CHRT(APPLET(chrt, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
diff --git a/include/libbb.h b/include/libbb.h index 46860c614..a8b9b5bcf 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -769,6 +769,7 @@ extern void selinux_or_die(void); | |||
769 | extern int restricted_shell(const char *shell); | 769 | extern int restricted_shell(const char *shell); |
770 | extern void setup_environment(const char *shell, int loginshell, int changeenv, const struct passwd *pw); | 770 | extern void setup_environment(const char *shell, int loginshell, int changeenv, const struct passwd *pw); |
771 | extern int correct_password(const struct passwd *pw); | 771 | extern int correct_password(const struct passwd *pw); |
772 | /* Returns a ptr to static storage */ | ||
772 | extern char *pw_encrypt(const char *clear, const char *salt); | 773 | extern char *pw_encrypt(const char *clear, const char *salt); |
773 | extern int obscure(const char *old, const char *newval, const struct passwd *pwdp); | 774 | extern int obscure(const char *old, const char *newval, const struct passwd *pwdp); |
774 | extern int index_in_str_array(const char * const string_array[], const char *key); | 775 | extern int index_in_str_array(const char * const string_array[], const char *key); |
@@ -776,7 +777,18 @@ extern int index_in_substr_array(const char * const string_array[], const char * | |||
776 | extern void print_login_issue(const char *issue_file, const char *tty); | 777 | extern void print_login_issue(const char *issue_file, const char *tty); |
777 | extern void print_login_prompt(void); | 778 | extern void print_login_prompt(void); |
778 | 779 | ||
779 | extern void crypt_make_salt(char *p, int cnt); | 780 | /* rnd is additional random input. New one is returned. |
781 | * Useful if you call crypt_make_salt many times in a row: | ||
782 | * rnd = crypt_make_salt(buf1, 4, 0); | ||
783 | * rnd = crypt_make_salt(buf2, 4, rnd); | ||
784 | * rnd = crypt_make_salt(buf3, 4, rnd); | ||
785 | * (otherwise we risk having same salt generated) | ||
786 | */ | ||
787 | extern int crypt_make_salt(char *p, int cnt, int rnd); | ||
788 | |||
789 | /* Returns number of lines changed, or -1 on error */ | ||
790 | extern int update_passwd(const char *filename, const char *username, | ||
791 | const char *new_pw); | ||
780 | 792 | ||
781 | int get_terminal_width_height(const int fd, int *width, int *height); | 793 | int get_terminal_width_height(const int fd, int *width, int *height); |
782 | 794 | ||
diff --git a/include/usage.h b/include/usage.h index 29a4991fb..9c77c70d8 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -452,7 +452,7 @@ | |||
452 | " F Input from file" | 452 | " F Input from file" |
453 | 453 | ||
454 | #define crond_trivial_usage \ | 454 | #define crond_trivial_usage \ |
455 | "-d[#] -c <crondir> -f -b" | 455 | "-d[#] -c crondir -f -b" |
456 | #define crond_full_usage \ | 456 | #define crond_full_usage \ |
457 | " -d [#] -l [#] -S -L logfile -f -b -c dir\n" \ | 457 | " -d [#] -l [#] -S -L logfile -f -b -c dir\n" \ |
458 | " -d num Debug level\n" \ | 458 | " -d num Debug level\n" \ |
@@ -466,8 +466,8 @@ | |||
466 | #define crontab_trivial_usage \ | 466 | #define crontab_trivial_usage \ |
467 | "[-c dir] {file|-}|[-u|-l|-e|-d user]" | 467 | "[-c dir] {file|-}|[-u|-l|-e|-d user]" |
468 | #define crontab_full_usage \ | 468 | #define crontab_full_usage \ |
469 | " file <opts> Replace crontab from file\n" \ | 469 | " file [opts] Replace crontab from file\n" \ |
470 | " - <opts> Replace crontab from stdin\n" \ | 470 | " - [opts] Replace crontab from stdin\n" \ |
471 | " -u user Specify user\n" \ | 471 | " -u user Specify user\n" \ |
472 | " -l [user] List crontab for user\n" \ | 472 | " -l [user] List crontab for user\n" \ |
473 | " -e [user] Edit crontab for user\n" \ | 473 | " -e [user] Edit crontab for user\n" \ |
@@ -1216,7 +1216,7 @@ | |||
1216 | "-rw-rw-r-- 1 andersen andersen 554058 Apr 14 17:49 /tmp/busybox.tar.gz\n" | 1216 | "-rw-rw-r-- 1 andersen andersen 554058 Apr 14 17:49 /tmp/busybox.tar.gz\n" |
1217 | 1217 | ||
1218 | #define halt_trivial_usage \ | 1218 | #define halt_trivial_usage \ |
1219 | "[-d<delay>] [-n<nosync>] [-f<force>]" | 1219 | "[-d delay] [-n] [-f]" |
1220 | #define halt_full_usage \ | 1220 | #define halt_full_usage \ |
1221 | "Halt the system" \ | 1221 | "Halt the system" \ |
1222 | "\n\nOptions:\n" \ | 1222 | "\n\nOptions:\n" \ |
@@ -1332,14 +1332,14 @@ | |||
1332 | "sage\n" | 1332 | "sage\n" |
1333 | 1333 | ||
1334 | #define httpd_trivial_usage \ | 1334 | #define httpd_trivial_usage \ |
1335 | "[-c <conf file>]" \ | 1335 | "[-c conffile]" \ |
1336 | " [-p <port>]" \ | 1336 | " [-p port]" \ |
1337 | " [-i] [-f]" \ | 1337 | " [-i] [-f]" \ |
1338 | USE_FEATURE_HTTPD_SETUID(" [-u user[:grp]]") \ | 1338 | USE_FEATURE_HTTPD_SETUID(" [-u user[:grp]]") \ |
1339 | USE_FEATURE_HTTPD_BASIC_AUTH(" [-r <realm>]") \ | 1339 | USE_FEATURE_HTTPD_BASIC_AUTH(" [-r realm]") \ |
1340 | USE_FEATURE_HTTPD_AUTH_MD5(" [-m pass]") \ | 1340 | USE_FEATURE_HTTPD_AUTH_MD5(" [-m pass]") \ |
1341 | " [-h home]" \ | 1341 | " [-h home]" \ |
1342 | " [-d/-e <string>]" | 1342 | " [-d/-e string]" |
1343 | #define httpd_full_usage \ | 1343 | #define httpd_full_usage \ |
1344 | "Listen for incoming http server requests" \ | 1344 | "Listen for incoming http server requests" \ |
1345 | "\n\nOptions:\n" \ | 1345 | "\n\nOptions:\n" \ |
@@ -1388,27 +1388,27 @@ | |||
1388 | "uid=1000(andersen) gid=1000(andersen)\n" | 1388 | "uid=1000(andersen) gid=1000(andersen)\n" |
1389 | 1389 | ||
1390 | #define ifconfig_trivial_usage \ | 1390 | #define ifconfig_trivial_usage \ |
1391 | USE_FEATURE_IFCONFIG_STATUS("[-a]") " <interface> [<address>]" | 1391 | USE_FEATURE_IFCONFIG_STATUS("[-a]") " interface [address]" |
1392 | #define ifconfig_full_usage \ | 1392 | #define ifconfig_full_usage \ |
1393 | "Configure a network interface" \ | 1393 | "Configure a network interface" \ |
1394 | "\n\nOptions:\n" \ | 1394 | "\n\nOptions:\n" \ |
1395 | USE_FEATURE_IPV6( \ | 1395 | USE_FEATURE_IPV6( \ |
1396 | " [add <address>[/<prefixlen>]]\n") \ | 1396 | " [add ADDRESS[/PREFIXLEN]]\n") \ |
1397 | USE_FEATURE_IPV6( \ | 1397 | USE_FEATURE_IPV6( \ |
1398 | " [del <address>[/<prefixlen>]]\n") \ | 1398 | " [del ADDRESS[/PREFIXLEN]]\n") \ |
1399 | " [[-]broadcast [<address>]] [[-]pointopoint [<address>]]\n" \ | 1399 | " [[-]broadcast [ADDRESS]] [[-]pointopoint [ADDRESS]]\n" \ |
1400 | " [netmask <address>] [dstaddr <address>]\n" \ | 1400 | " [netmask ADDRESS] [dstaddr ADDRESS]\n" \ |
1401 | USE_FEATURE_IFCONFIG_SLIP( \ | 1401 | USE_FEATURE_IFCONFIG_SLIP( \ |
1402 | " [outfill <NN>] [keepalive <NN>]\n") \ | 1402 | " [outfill NN] [keepalive NN]\n") \ |
1403 | " " USE_FEATURE_IFCONFIG_HW("[hw ether <address>] ") "[metric <NN>] [mtu <NN>]\n" \ | 1403 | " " USE_FEATURE_IFCONFIG_HW("[hw ether ADDRESS] ") "[metric NN] [mtu NN]\n" \ |
1404 | " [[-]trailers] [[-]arp] [[-]allmulti]\n" \ | 1404 | " [[-]trailers] [[-]arp] [[-]allmulti]\n" \ |
1405 | " [multicast] [[-]promisc] [txqueuelen <NN>] [[-]dynamic]\n" \ | 1405 | " [multicast] [[-]promisc] [txqueuelen NN] [[-]dynamic]\n" \ |
1406 | USE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ( \ | 1406 | USE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ( \ |
1407 | " [mem_start <NN>] [io_addr <NN>] [irq <NN>]\n") \ | 1407 | " [mem_start NN] [io_addr NN] [irq NN]\n") \ |
1408 | " [up|down] ..." | 1408 | " [up|down] ..." |
1409 | 1409 | ||
1410 | #define ifup_trivial_usage \ | 1410 | #define ifup_trivial_usage \ |
1411 | "<-ahinv> <ifaces...>" | 1411 | "[-ahinv] ifaces..." |
1412 | #define ifup_full_usage \ | 1412 | #define ifup_full_usage \ |
1413 | "Options:\n" \ | 1413 | "Options:\n" \ |
1414 | " -a De/configure all interfaces automatically\n" \ | 1414 | " -a De/configure all interfaces automatically\n" \ |
@@ -1420,7 +1420,7 @@ | |||
1420 | " -f Force de/configuration" | 1420 | " -f Force de/configuration" |
1421 | 1421 | ||
1422 | #define ifdown_trivial_usage \ | 1422 | #define ifdown_trivial_usage \ |
1423 | "<-ahinv> <ifaces...>" | 1423 | "[-ahinv] ifaces..." |
1424 | #define ifdown_full_usage \ | 1424 | #define ifdown_full_usage \ |
1425 | "Options:\n" \ | 1425 | "Options:\n" \ |
1426 | " -a De/configure all interfaces automatically\n" \ | 1426 | " -a De/configure all interfaces automatically\n" \ |
@@ -1587,7 +1587,7 @@ | |||
1587 | " -x Do not export externs" | 1587 | " -x Do not export externs" |
1588 | 1588 | ||
1589 | #define install_trivial_usage \ | 1589 | #define install_trivial_usage \ |
1590 | "[-cgmops] [sources] <dest|directory>" | 1590 | "[-cgmops] [sources] dest|directory" |
1591 | #define install_full_usage \ | 1591 | #define install_full_usage \ |
1592 | "Copy files and set attributes" \ | 1592 | "Copy files and set attributes" \ |
1593 | "\n\nOptions:\n" \ | 1593 | "\n\nOptions:\n" \ |
@@ -1634,7 +1634,7 @@ | |||
1634 | " SCOPE-ID := [host | link | global | NUMBER]" | 1634 | " SCOPE-ID := [host | link | global | NUMBER]" |
1635 | 1635 | ||
1636 | #define ipcalc_trivial_usage \ | 1636 | #define ipcalc_trivial_usage \ |
1637 | "[OPTION]... <ADDRESS>[[/]<NETMASK>] [NETMASK]" | 1637 | "[OPTION]... ADDRESS[[/]NETMASK] [NETMASK]" |
1638 | #define ipcalc_full_usage \ | 1638 | #define ipcalc_full_usage \ |
1639 | "Calculate IP network settings from a IP address" \ | 1639 | "Calculate IP network settings from a IP address" \ |
1640 | "\n\nOptions:" \ | 1640 | "\n\nOptions:" \ |
@@ -1778,7 +1778,7 @@ | |||
1778 | " reached" | 1778 | " reached" |
1779 | 1779 | ||
1780 | #define setarch_trivial_usage \ | 1780 | #define setarch_trivial_usage \ |
1781 | "<personality> <program> [args ...]" | 1781 | "personality program [args ...]" |
1782 | #define setarch_full_usage \ | 1782 | #define setarch_full_usage \ |
1783 | "Personality may be:\n" \ | 1783 | "Personality may be:\n" \ |
1784 | " linux32 Set 32bit uname emulation\n" \ | 1784 | " linux32 Set 32bit uname emulation\n" \ |
@@ -2502,7 +2502,7 @@ | |||
2502 | "to standard output. With no FILE, or when FILE is -, read standard input." | 2502 | "to standard output. With no FILE, or when FILE is -, read standard input." |
2503 | 2503 | ||
2504 | #define openvt_trivial_usage \ | 2504 | #define openvt_trivial_usage \ |
2505 | "<vtnum> <COMMAND> [ARGS...]" | 2505 | "VTNUM COMMAND [ARGS...]" |
2506 | #define openvt_full_usage \ | 2506 | #define openvt_full_usage \ |
2507 | "Start a command on a new virtual terminal" | 2507 | "Start a command on a new virtual terminal" |
2508 | #define openvt_example_usage \ | 2508 | #define openvt_example_usage \ |
@@ -2520,8 +2520,17 @@ | |||
2520 | " -l Locks (disables) the specified user account\n" \ | 2520 | " -l Locks (disables) the specified user account\n" \ |
2521 | " -u Unlocks (re-enables) the specified user account" | 2521 | " -u Unlocks (re-enables) the specified user account" |
2522 | 2522 | ||
2523 | #define chpasswd_trivial_usage \ | ||
2524 | "[--md5|--encrypt]" | ||
2525 | #define chpasswd_full_usage \ | ||
2526 | "Read user:password information from stdin\n" \ | ||
2527 | "and update /etc/passwd accordingly." \ | ||
2528 | "\n\nOptions:" \ | ||
2529 | "\n -e, --encrypt Supplied passwords are in encrypted form" \ | ||
2530 | "\n -m, --md5 Use MD5 encryption instead of DES" | ||
2531 | |||
2523 | #define patch_trivial_usage \ | 2532 | #define patch_trivial_usage \ |
2524 | "[-p<num>] [-i <diff>]" | 2533 | "[-p num] [-i diff]" |
2525 | #define patch_full_usage \ | 2534 | #define patch_full_usage \ |
2526 | " -p NUM Strip NUM leading components from file names\n" \ | 2535 | " -p NUM Strip NUM leading components from file names\n" \ |
2527 | " -i DIFF Read DIFF instead of stdin" | 2536 | " -i DIFF Read DIFF instead of stdin" |
@@ -2612,7 +2621,7 @@ | |||
2612 | "the new root file system" | 2621 | "the new root file system" |
2613 | 2622 | ||
2614 | #define poweroff_trivial_usage \ | 2623 | #define poweroff_trivial_usage \ |
2615 | "[-d<delay>] [-n<nosync>] [-f<force>]" | 2624 | "[-d delay] [-n] [-f]" |
2616 | #define poweroff_full_usage \ | 2625 | #define poweroff_full_usage \ |
2617 | "Halt and shut off power" \ | 2626 | "Halt and shut off power" \ |
2618 | "\n\nOptions:\n" \ | 2627 | "\n\nOptions:\n" \ |
@@ -2729,9 +2738,9 @@ | |||
2729 | "[OPTIONS]..." | 2738 | "[OPTIONS]..." |
2730 | #define readprofile_full_usage \ | 2739 | #define readprofile_full_usage \ |
2731 | "Options:\n" \ | 2740 | "Options:\n" \ |
2732 | " -m <mapfile> (Default: /boot/System.map)\n" \ | 2741 | " -m mapfile (Default: /boot/System.map)\n" \ |
2733 | " -p <profile> (Default: /proc/profile)\n" \ | 2742 | " -p profile (Default: /proc/profile)\n" \ |
2734 | " -M <mult> Set the profiling multiplier to <mult>\n" \ | 2743 | " -M mult Set the profiling multiplier to mult\n" \ |
2735 | " -i Print only info about the sampling step\n" \ | 2744 | " -i Print only info about the sampling step\n" \ |
2736 | " -v Verbose\n" \ | 2745 | " -v Verbose\n" \ |
2737 | " -a Print all symbols, even if count is 0\n" \ | 2746 | " -a Print all symbols, even if count is 0\n" \ |
@@ -2746,7 +2755,7 @@ | |||
2746 | "Return the absolute pathnames of given argument" | 2755 | "Return the absolute pathnames of given argument" |
2747 | 2756 | ||
2748 | #define reboot_trivial_usage \ | 2757 | #define reboot_trivial_usage \ |
2749 | "[-d<delay>] [-n<nosync>] [-f<force>]" | 2758 | "[-d delay] [-n] [-f]" |
2750 | #define reboot_full_usage \ | 2759 | #define reboot_full_usage \ |
2751 | "Reboot the system" \ | 2760 | "Reboot the system" \ |
2752 | "\n\nOptions:\n" \ | 2761 | "\n\nOptions:\n" \ |
@@ -3083,21 +3092,21 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when | |||
3083 | "\n\nOptions:" \ | 3092 | "\n\nOptions:" \ |
3084 | "\n -S|--start Start" \ | 3093 | "\n -S|--start Start" \ |
3085 | "\n -K|--stop Stop" \ | 3094 | "\n -K|--stop Stop" \ |
3086 | "\n -a|--startas <pathname> Starts process specified by pathname" \ | 3095 | "\n -a|--startas pathname Starts process specified by pathname" \ |
3087 | "\n -b|--background Force process into background" \ | 3096 | "\n -b|--background Force process into background" \ |
3088 | "\n -u|--user <username>|<uid> Stop this user's processes" \ | 3097 | "\n -u|--user username|uid Stop this user's processes" \ |
3089 | "\n -x|--exec <executable> Program to either start or check" \ | 3098 | "\n -x|--exec executable Program to either start or check" \ |
3090 | "\n -m|--make-pidfile Create the -p file and enter pid in it" \ | 3099 | "\n -m|--make-pidfile Create the -p file and enter pid in it" \ |
3091 | "\n -n|--name <process-name> Stop processes with this name" \ | 3100 | "\n -n|--name process-name Stop processes with this name" \ |
3092 | "\n -p|--pidfile <pid-file> Save or load pid using a pid-file" \ | 3101 | "\n -p|--pidfile pid-file Save or load pid using a pid-file" \ |
3093 | "\n -q|--quiet Quiet" \ | 3102 | "\n -q|--quiet Quiet" \ |
3094 | USE_FEATURE_START_STOP_DAEMON_FANCY( \ | 3103 | USE_FEATURE_START_STOP_DAEMON_FANCY( \ |
3095 | "\n -o|--oknodo Exit status 0 if nothing done" \ | 3104 | "\n -o|--oknodo Exit status 0 if nothing done" \ |
3096 | "\n -v|--verbose Verbose" \ | 3105 | "\n -v|--verbose Verbose" \ |
3097 | "\n -N|--nicelevel <N> Add N to process's nice level" \ | 3106 | "\n -N|--nicelevel N Add N to process's nice level" \ |
3098 | ) \ | 3107 | ) \ |
3099 | "\n -s|--signal <signal> Signal to send (default TERM)" \ | 3108 | "\n -s|--signal signal Signal to send (default TERM)" \ |
3100 | "\n -c|--chuid <user>[:[<group>]] Change to specified user/group" | 3109 | "\n -c|--chuid user[:[group]] Change to specified user/group" |
3101 | 3110 | ||
3102 | #define stat_trivial_usage \ | 3111 | #define stat_trivial_usage \ |
3103 | "[OPTION] FILE..." | 3112 | "[OPTION] FILE..." |
@@ -3257,7 +3266,7 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when | |||
3257 | "sysctl [-n] variable ...\n" \ | 3266 | "sysctl [-n] variable ...\n" \ |
3258 | "sysctl [-n] -w variable=value ...\n" \ | 3267 | "sysctl [-n] -w variable=value ...\n" \ |
3259 | "sysctl [-n] -a\n" \ | 3268 | "sysctl [-n] -a\n" \ |
3260 | "sysctl [-n] -p <file> (default /etc/sysctl.conf)\n" \ | 3269 | "sysctl [-n] -p file (default /etc/sysctl.conf)\n" \ |
3261 | "sysctl [-n] -A\n" | 3270 | "sysctl [-n] -A\n" |
3262 | 3271 | ||
3263 | #define syslogd_trivial_usage \ | 3272 | #define syslogd_trivial_usage \ |
@@ -3747,7 +3756,7 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when | |||
3747 | " -a Lock all VTs" | 3756 | " -a Lock all VTs" |
3748 | 3757 | ||
3749 | #define watch_trivial_usage \ | 3758 | #define watch_trivial_usage \ |
3750 | "[-n <seconds>] [-t] COMMAND..." | 3759 | "[-n seconds] [-t] COMMAND..." |
3751 | #define watch_full_usage \ | 3760 | #define watch_full_usage \ |
3752 | "Execute a program periodically" \ | 3761 | "Execute a program periodically" \ |
3753 | "\n\nOptions:\n" \ | 3762 | "\n\nOptions:\n" \ |
@@ -3760,7 +3769,7 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when | |||
3760 | "Mon Dec 17 10:31:44 GMT 2000" | 3769 | "Mon Dec 17 10:31:44 GMT 2000" |
3761 | 3770 | ||
3762 | #define watchdog_trivial_usage \ | 3771 | #define watchdog_trivial_usage \ |
3763 | "[-t <seconds>] [-F] DEV" | 3772 | "[-t seconds] [-F] DEV" |
3764 | #define watchdog_full_usage \ | 3773 | #define watchdog_full_usage \ |
3765 | "Periodically write to watchdog device DEV" \ | 3774 | "Periodically write to watchdog device DEV" \ |
3766 | "\n\nOptions:\n" \ | 3775 | "\n\nOptions:\n" \ |
diff --git a/libbb/Kbuild b/libbb/Kbuild index 659586717..c0cbe1aa9 100644 --- a/libbb/Kbuild +++ b/libbb/Kbuild | |||
@@ -104,7 +104,8 @@ lib-y += xreadlink.o | |||
104 | lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o | 104 | lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o |
105 | lib-$(CONFIG_LOSETUP) += loop.o | 105 | lib-$(CONFIG_LOSETUP) += loop.o |
106 | lib-$(CONFIG_FEATURE_MTAB_SUPPORT) += mtab.o | 106 | lib-$(CONFIG_FEATURE_MTAB_SUPPORT) += mtab.o |
107 | lib-$(CONFIG_PASSWD) += pw_encrypt.o crypt_make_salt.o | 107 | lib-$(CONFIG_PASSWD) += pw_encrypt.o crypt_make_salt.o update_passwd.o |
108 | lib-$(CONFIG_CHPASSWD) += pw_encrypt.o crypt_make_salt.o update_passwd.o | ||
108 | lib-$(CONFIG_CRYPTPW) += pw_encrypt.o crypt_make_salt.o | 109 | lib-$(CONFIG_CRYPTPW) += pw_encrypt.o crypt_make_salt.o |
109 | lib-$(CONFIG_SULOGIN) += pw_encrypt.o | 110 | lib-$(CONFIG_SULOGIN) += pw_encrypt.o |
110 | lib-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) += pw_encrypt.o | 111 | lib-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) += pw_encrypt.o |
diff --git a/libbb/crypt_make_salt.c b/libbb/crypt_make_salt.c index 12e96328f..ebdf02420 100644 --- a/libbb/crypt_make_salt.c +++ b/libbb/crypt_make_salt.c | |||
@@ -24,12 +24,9 @@ static int i64c(int i) | |||
24 | return ('a' - 38 + i); | 24 | return ('a' - 38 + i); |
25 | } | 25 | } |
26 | 26 | ||
27 | 27 | int crypt_make_salt(char *p, int cnt, int x) | |
28 | void crypt_make_salt(char *p, int cnt) | ||
29 | { | 28 | { |
30 | unsigned x = x; /* it's pointless to initialize it anyway :) */ | 29 | x += getpid() + time(NULL); |
31 | |||
32 | x += getpid() + time(NULL) + clock(); | ||
33 | do { | 30 | do { |
34 | /* x = (x*1664525 + 1013904223) % 2^32 generator is lame | 31 | /* x = (x*1664525 + 1013904223) % 2^32 generator is lame |
35 | * (low-order bit is not "random", etc...), | 32 | * (low-order bit is not "random", etc...), |
@@ -44,5 +41,5 @@ void crypt_make_salt(char *p, int cnt) | |||
44 | *p++ = i64c(x >> 22); | 41 | *p++ = i64c(x >> 22); |
45 | } while (--cnt); | 42 | } while (--cnt); |
46 | *p = '\0'; | 43 | *p = '\0'; |
44 | return x; | ||
47 | } | 45 | } |
48 | |||
diff --git a/loginutils/Config.in b/loginutils/Config.in index f9ae122e4..63ae9b4db 100644 --- a/loginutils/Config.in +++ b/loginutils/Config.in | |||
@@ -180,6 +180,14 @@ config CRYPTPW | |||
180 | help | 180 | help |
181 | Applet for crypting a string. | 181 | Applet for crypting a string. |
182 | 182 | ||
183 | config CHPASSWD | ||
184 | bool "chpasswd" | ||
185 | default n | ||
186 | help | ||
187 | chpasswd reads a file of user name and password pairs from | ||
188 | standard input and uses this information to update a group of | ||
189 | existing users. | ||
190 | |||
183 | config SU | 191 | config SU |
184 | bool "su" | 192 | bool "su" |
185 | default n | 193 | default n |
diff --git a/loginutils/Kbuild b/loginutils/Kbuild index 1b1165a6e..3d0d777e8 100644 --- a/loginutils/Kbuild +++ b/loginutils/Kbuild | |||
@@ -8,6 +8,7 @@ lib-y:= | |||
8 | lib-$(CONFIG_ADDGROUP) += addgroup.o | 8 | lib-$(CONFIG_ADDGROUP) += addgroup.o |
9 | lib-$(CONFIG_ADDUSER) += adduser.o | 9 | lib-$(CONFIG_ADDUSER) += adduser.o |
10 | lib-$(CONFIG_CRYPTPW) += cryptpw.o | 10 | lib-$(CONFIG_CRYPTPW) += cryptpw.o |
11 | lib-$(CONFIG_CHPASSWD) += chpasswd.o | ||
11 | lib-$(CONFIG_GETTY) += getty.o | 12 | lib-$(CONFIG_GETTY) += getty.o |
12 | lib-$(CONFIG_LOGIN) += login.o | 13 | lib-$(CONFIG_LOGIN) += login.o |
13 | lib-$(CONFIG_PASSWD) += passwd.o | 14 | lib-$(CONFIG_PASSWD) += passwd.o |
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c index dd7304613..1c3059198 100644 --- a/loginutils/cryptpw.c +++ b/loginutils/cryptpw.c | |||
@@ -17,9 +17,9 @@ int cryptpw_main(int argc, char **argv) | |||
17 | /* Too ugly, and needs even more magic to handle endianness: */ | 17 | /* Too ugly, and needs even more magic to handle endianness: */ |
18 | //((uint32_t*)&salt)[0] = '$' + '1'*0x100 + '$'*0x10000; | 18 | //((uint32_t*)&salt)[0] = '$' + '1'*0x100 + '$'*0x10000; |
19 | /* Hope one day gcc will do it itself (inlining strcpy) */ | 19 | /* Hope one day gcc will do it itself (inlining strcpy) */ |
20 | crypt_make_salt(salt + 3, 4); /* md5 */ | 20 | crypt_make_salt(salt + 3, 4, 0); /* md5 */ |
21 | } else { | 21 | } else { |
22 | crypt_make_salt(salt, 1); /* des */ | 22 | crypt_make_salt(salt, 1, 0); /* des */ |
23 | } | 23 | } |
24 | 24 | ||
25 | puts(pw_encrypt(argv[optind] ? argv[optind] : xmalloc_getline(stdin), salt)); | 25 | puts(pw_encrypt(argv[optind] ? argv[optind] : xmalloc_getline(stdin), salt)); |
diff --git a/loginutils/passwd.c b/loginutils/passwd.c index 8f65c3d0b..cd98d4101 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c | |||
@@ -52,10 +52,10 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo) | |||
52 | } | 52 | } |
53 | 53 | ||
54 | /*memset(salt, 0, sizeof(salt)); - why?*/ | 54 | /*memset(salt, 0, sizeof(salt)); - why?*/ |
55 | crypt_make_salt(salt, 1); /* des */ | 55 | crypt_make_salt(salt, 1, 0); /* des */ |
56 | if (algo) { /* MD5 */ | 56 | if (algo) { /* MD5 */ |
57 | strcpy(salt, "$1$"); | 57 | strcpy(salt, "$1$"); |
58 | crypt_make_salt(salt + 3, 4); | 58 | crypt_make_salt(salt + 3, 4, 0); |
59 | } | 59 | } |
60 | ret = xstrdup(pw_encrypt(newp, salt)); /* returns ptr to static */ | 60 | ret = xstrdup(pw_encrypt(newp, salt)); /* returns ptr to static */ |
61 | /* whee, success! */ | 61 | /* whee, success! */ |
@@ -70,115 +70,6 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo) | |||
70 | return ret; | 70 | return ret; |
71 | } | 71 | } |
72 | 72 | ||
73 | |||
74 | static int update_passwd(const char *filename, const char *username, | ||
75 | const char *new_pw) | ||
76 | { | ||
77 | struct stat sb; | ||
78 | struct flock lock; | ||
79 | FILE *old_fp; | ||
80 | FILE *new_fp; | ||
81 | char *new_name; | ||
82 | char *last_char; | ||
83 | unsigned user_len; | ||
84 | int old_fd; | ||
85 | int new_fd; | ||
86 | int i; | ||
87 | int ret = 1; /* failure */ | ||
88 | |||
89 | logmode = LOGMODE_STDIO; | ||
90 | /* New passwd file, "/etc/passwd+" for now */ | ||
91 | new_name = xasprintf("%s+", filename); | ||
92 | last_char = &new_name[strlen(new_name)-1]; | ||
93 | username = xasprintf("%s:", username); | ||
94 | user_len = strlen(username); | ||
95 | |||
96 | old_fp = fopen(filename, "r+"); | ||
97 | if (!old_fp) | ||
98 | goto free_mem; | ||
99 | old_fd = fileno(old_fp); | ||
100 | |||
101 | /* Try to create "/etc/passwd+". Wait if it exists. */ | ||
102 | i = 30; | ||
103 | do { | ||
104 | // FIXME: on last iteration try w/o O_EXCL but with O_TRUNC? | ||
105 | new_fd = open(new_name, O_WRONLY|O_CREAT|O_EXCL,0600); | ||
106 | if (new_fd >= 0) goto created; | ||
107 | if (errno != EEXIST) break; | ||
108 | usleep(100000); /* 0.1 sec */ | ||
109 | } while (--i); | ||
110 | bb_perror_msg("cannot create '%s'", new_name); | ||
111 | goto close_old_fp; | ||
112 | created: | ||
113 | if (!fstat(old_fd, &sb)) { | ||
114 | fchmod(new_fd, sb.st_mode & 0777); /* ignore errors */ | ||
115 | fchown(new_fd, sb.st_uid, sb.st_gid); | ||
116 | } | ||
117 | new_fp = fdopen(new_fd, "w"); | ||
118 | if (!new_fp) { | ||
119 | close(new_fd); | ||
120 | goto unlink_new; | ||
121 | } | ||
122 | |||
123 | /* Backup file is "/etc/passwd-" */ | ||
124 | last_char[0] = '-'; | ||
125 | /* Delete old one, create new as a hardlink to current */ | ||
126 | i = (unlink(new_name) && errno != ENOENT); | ||
127 | if (i || link(filename, new_name)) | ||
128 | bb_perror_msg("warning: cannot create backup copy '%s'", new_name); | ||
129 | last_char[0] = '+'; | ||
130 | |||
131 | /* Lock the password file before updating */ | ||
132 | lock.l_type = F_WRLCK; | ||
133 | lock.l_whence = SEEK_SET; | ||
134 | lock.l_start = 0; | ||
135 | lock.l_len = 0; | ||
136 | if (fcntl(old_fd, F_SETLK, &lock) < 0) | ||
137 | bb_perror_msg("warning: cannot lock '%s'", filename); | ||
138 | lock.l_type = F_UNLCK; | ||
139 | |||
140 | /* Read current password file, write updated one */ | ||
141 | while (1) { | ||
142 | char *line = xmalloc_fgets(old_fp); | ||
143 | if (!line) break; /* EOF/error */ | ||
144 | if (strncmp(username, line, user_len) == 0) { | ||
145 | /* we have a match with "username:"... */ | ||
146 | const char *cp = line + user_len; | ||
147 | /* now cp -> old passwd, skip it: */ | ||
148 | cp = strchr(cp, ':'); | ||
149 | if (!cp) cp = ""; | ||
150 | /* now cp -> ':' after old passwd or -> "" */ | ||
151 | fprintf(new_fp, "%s%s%s", username, new_pw, cp); | ||
152 | /* Erase password in memory */ | ||
153 | } else | ||
154 | fputs(line, new_fp); | ||
155 | free(line); | ||
156 | } | ||
157 | fcntl(old_fd, F_SETLK, &lock); | ||
158 | |||
159 | /* We do want all of them to execute, thus | instead of || */ | ||
160 | if ((ferror(old_fp) | fflush(new_fp) | fsync(new_fd) | fclose(new_fp)) | ||
161 | || rename(new_name, filename) | ||
162 | ) { | ||
163 | /* At least one of those failed */ | ||
164 | goto unlink_new; | ||
165 | } | ||
166 | ret = 0; /* whee, success! */ | ||
167 | |||
168 | unlink_new: | ||
169 | if (ret) unlink(new_name); | ||
170 | |||
171 | close_old_fp: | ||
172 | fclose(old_fp); | ||
173 | |||
174 | free_mem: | ||
175 | if (ENABLE_FEATURE_CLEAN_UP) free(new_name); | ||
176 | if (ENABLE_FEATURE_CLEAN_UP) free((char*)username); | ||
177 | logmode = LOGMODE_BOTH; | ||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | |||
182 | int passwd_main(int argc, char **argv); | 73 | int passwd_main(int argc, char **argv); |
183 | int passwd_main(int argc, char **argv) | 74 | int passwd_main(int argc, char **argv) |
184 | { | 75 | { |
@@ -192,6 +83,7 @@ int passwd_main(int argc, char **argv) | |||
192 | /*STATE_ALGO_des = 0x20, not needed yet */ | 83 | /*STATE_ALGO_des = 0x20, not needed yet */ |
193 | }; | 84 | }; |
194 | unsigned opt; | 85 | unsigned opt; |
86 | int rc; | ||
195 | const char *opt_a = ""; | 87 | const char *opt_a = ""; |
196 | const char *filename; | 88 | const char *filename; |
197 | char *myname; | 89 | char *myname; |
@@ -278,12 +170,11 @@ int passwd_main(int argc, char **argv) | |||
278 | signal(SIGQUIT, SIG_IGN); | 170 | signal(SIGQUIT, SIG_IGN); |
279 | umask(077); | 171 | umask(077); |
280 | xsetuid(0); | 172 | xsetuid(0); |
281 | if (update_passwd(filename, name, newp) != 0) { | 173 | rc = update_passwd(filename, name, newp); |
282 | /* LOGMODE_BOTH */ | 174 | logmode = LOGMODE_BOTH; |
175 | if (rc < 0) | ||
283 | bb_error_msg_and_die("cannot update password file %s", | 176 | bb_error_msg_and_die("cannot update password file %s", |
284 | filename); | 177 | filename); |
285 | } | ||
286 | /* LOGMODE_BOTH */ | ||
287 | bb_info_msg("Password for %s changed by %s", name, myname); | 178 | bb_info_msg("Password for %s changed by %s", name, myname); |
288 | 179 | ||
289 | if (ENABLE_FEATURE_CLEAN_UP) free(newp); | 180 | if (ENABLE_FEATURE_CLEAN_UP) free(newp); |
diff --git a/scripts/defconfig b/scripts/defconfig index 088ff791a..4709b2234 100644 --- a/scripts/defconfig +++ b/scripts/defconfig | |||
@@ -376,6 +376,7 @@ CONFIG_FEATURE_SECURETTY=y | |||
376 | CONFIG_PASSWD=y | 376 | CONFIG_PASSWD=y |
377 | CONFIG_FEATURE_PASSWD_WEAK_CHECK=y | 377 | CONFIG_FEATURE_PASSWD_WEAK_CHECK=y |
378 | CONFIG_CRYPTPW=y | 378 | CONFIG_CRYPTPW=y |
379 | CONFIG_CHPASSWD=y | ||
379 | CONFIG_SU=y | 380 | CONFIG_SU=y |
380 | CONFIG_FEATURE_SU_SYSLOG=y | 381 | CONFIG_FEATURE_SU_SYSLOG=y |
381 | CONFIG_FEATURE_SU_CHECKS_SHELLS=y | 382 | CONFIG_FEATURE_SU_CHECKS_SHELLS=y |
diff --git a/scripts/trylink b/scripts/trylink index ddd7fb179..cbd702338 100755 --- a/scripts/trylink +++ b/scripts/trylink | |||
@@ -22,9 +22,11 @@ try "-Wl,--start-group $l_list -Wl,--end-group" "$@" \ | |||
22 | cat busybox_ld.err | 22 | cat busybox_ld.err |
23 | exit 1 | 23 | exit 1 |
24 | } | 24 | } |
25 | mv busybox_unstripped busybox_unstripped.tmp | ||
25 | 26 | ||
26 | # Now try to remove each lib and build without. | 27 | # Now try to remove each lib and build without. |
27 | # Stop when no lib can be removed. | 28 | # Stop when no lib can be removed. |
29 | ever_discarded=false | ||
28 | while test "$BBOX_LIB_LIST"; do | 30 | while test "$BBOX_LIB_LIST"; do |
29 | $debug && echo "Trying libraries: $BBOX_LIB_LIST" | 31 | $debug && echo "Trying libraries: $BBOX_LIB_LIST" |
30 | all_needed=true | 32 | all_needed=true |
@@ -36,6 +38,7 @@ while test "$BBOX_LIB_LIST"; do | |||
36 | echo "Library $one is not needed" | 38 | echo "Library $one is not needed" |
37 | BBOX_LIB_LIST="$without_one" | 39 | BBOX_LIB_LIST="$without_one" |
38 | all_needed=false | 40 | all_needed=false |
41 | ever_discarded=true | ||
39 | else | 42 | else |
40 | echo "Library $one is needed" | 43 | echo "Library $one is needed" |
41 | fi | 44 | fi |
@@ -48,7 +51,11 @@ while test "$BBOX_LIB_LIST"; do | |||
48 | #echo "$BBOX_LIB_LIST" | grep -q ' ' || break | 51 | #echo "$BBOX_LIB_LIST" | grep -q ' ' || break |
49 | done | 52 | done |
50 | 53 | ||
51 | # Ok, make the binary | 54 | mv busybox_unstripped.tmp busybox_unstripped |
52 | echo "Final link with: $BBOX_LIB_LIST" | 55 | $ever_discarded && { |
53 | l_list=`echo "$BBOX_LIB_LIST" | sed -e 's/ / -l/g' -e 's/^/-l/'` | 56 | # Ok, make the binary |
54 | try "-Wl,--start-group $l_list -Wl,--end-group" "$@" | 57 | echo "Final link with: $BBOX_LIB_LIST" |
58 | l_list=`echo "$BBOX_LIB_LIST" | sed -e 's/ / -l/g' -e 's/^/-l/'` | ||
59 | try "-Wl,--start-group $l_list -Wl,--end-group" "$@" | ||
60 | } | ||
61 | exit 0 # Ensure "success" exit code | ||