source: branches/3.2/mindi-busybox/loginutils/chpasswd.c @ 3232

Last change on this file since 3232 was 3232, checked in by bruno, 5 years ago
  • Update mindi-busybox to 1.21.1
  • Property svn:eol-style set to native
File size: 2.6 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * chpasswd.c
4 *
5 * Written for SLIND (from passwd.c) by Alexander Shishkin <virtuoso@slind.org>
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
7 */
8#include "libbb.h"
9
10//usage:#define chpasswd_trivial_usage
11//usage:    IF_LONG_OPTS("[--md5|--encrypted]") IF_NOT_LONG_OPTS("[-m|-e]")
12//usage:#define chpasswd_full_usage "\n\n"
13//usage:       "Read user:password from stdin and update /etc/passwd\n"
14//usage:    IF_LONG_OPTS(
15//usage:     "\n    -e,--encrypted  Supplied passwords are in encrypted form"
16//usage:     "\n    -m,--md5    Use MD5 encryption instead of DES"
17//usage:    )
18//usage:    IF_NOT_LONG_OPTS(
19//usage:     "\n    -e  Supplied passwords are in encrypted form"
20//usage:     "\n    -m  Use MD5 encryption instead of DES"
21//usage:    )
22
23//TODO: implement -c ALGO
24
25#if ENABLE_LONG_OPTS
26static const char chpasswd_longopts[] ALIGN1 =
27    "encrypted\0" No_argument "e"
28    "md5\0"       No_argument "m"
29    ;
30#endif
31
32#define OPT_ENC  1
33#define OPT_MD5  2
34
35int chpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
36int chpasswd_main(int argc UNUSED_PARAM, char **argv)
37{
38    char *name;
39    int opt;
40
41    if (getuid() != 0)
42        bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
43
44    opt_complementary = "m--e:e--m";
45    IF_LONG_OPTS(applet_long_options = chpasswd_longopts;)
46    opt = getopt32(argv, "em");
47
48    while ((name = xmalloc_fgetline(stdin)) != NULL) {
49        char *free_me;
50        char *pass;
51        int rc;
52
53        pass = strchr(name, ':');
54        if (!pass)
55            bb_error_msg_and_die("missing new password");
56        *pass++ = '\0';
57
58        xuname2uid(name); /* dies if there is no such user */
59
60        free_me = NULL;
61        if (!(opt & OPT_ENC)) {
62            char salt[sizeof("$N$XXXXXXXX")];
63
64            crypt_make_salt(salt, 1);
65            if (opt & OPT_MD5) {
66                salt[0] = '$';
67                salt[1] = '1';
68                salt[2] = '$';
69                crypt_make_salt(salt + 3, 4);
70            }
71            free_me = pass = pw_encrypt(pass, salt, 0);
72        }
73
74        /* This is rather complex: if user is not found in /etc/shadow,
75         * we try to find & change his passwd in /etc/passwd */
76#if ENABLE_FEATURE_SHADOWPASSWDS
77        rc = update_passwd(bb_path_shadow_file, name, pass, NULL);
78        if (rc > 0) /* password in /etc/shadow was updated */
79            pass = (char*)"x";
80        if (rc >= 0)
81            /* 0 = /etc/shadow missing (not an error), >0 = passwd changed in /etc/shadow */
82#endif
83            rc = update_passwd(bb_path_passwd_file, name, pass, NULL);
84        /* LOGMODE_BOTH logs to syslog also */
85        logmode = LOGMODE_BOTH;
86        if (rc < 0)
87            bb_error_msg_and_die("an error occurred updating password for %s", name);
88        if (rc)
89            bb_info_msg("Password for '%s' changed", name);
90        logmode = LOGMODE_STDIO;
91        free(name);
92        free(free_me);
93    }
94    return EXIT_SUCCESS;
95}
Note: See TracBrowser for help on using the repository browser.