1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#include "libbb.h"
36
37#if ENABLE_LONG_OPTS
38static const char chpasswd_longopts[] ALIGN1 =
39 "encrypted\0" No_argument "e"
40 "md5\0" No_argument "m"
41 "crypt-method\0" Required_argument "c"
42 "root\0" Required_argument "R"
43 ;
44#endif
45
46#define OPT_ENC 1
47#define OPT_MD5 2
48
49int chpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
50int chpasswd_main(int argc UNUSED_PARAM, char **argv)
51{
52 char *name;
53 const char *algo = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO;
54 const char *root = NULL;
55 int opt;
56
57 if (getuid() != 0)
58 bb_simple_error_msg_and_die(bb_msg_perm_denied_are_you_root);
59
60 opt = getopt32long(argv, "^" "emc:R:" "\0" "m--ec:e--mc:c--em",
61 chpasswd_longopts,
62 &algo, &root
63 );
64
65 if (root) {
66 xchroot(root);
67 }
68
69 while ((name = xmalloc_fgetline(stdin)) != NULL) {
70 char *free_me;
71 char *pass;
72 int rc;
73
74 pass = strchr(name, ':');
75 if (!pass)
76 bb_simple_error_msg_and_die("missing new password");
77 *pass++ = '\0';
78
79 xuname2uid(name);
80
81 free_me = NULL;
82 if (!(opt & OPT_ENC)) {
83 char salt[MAX_PW_SALT_LEN];
84
85 if (opt & OPT_MD5) {
86
87 algo = "md5";
88 }
89
90 crypt_make_pw_salt(salt, algo);
91 free_me = pass = pw_encrypt(pass, salt, 0);
92 }
93
94
95
96#if ENABLE_FEATURE_SHADOWPASSWDS
97 rc = update_passwd(bb_path_shadow_file, name, pass, NULL);
98 if (rc > 0)
99 pass = (char*)"x";
100 if (rc >= 0)
101
102#endif
103 rc = update_passwd(bb_path_passwd_file, name, pass, NULL);
104
105 logmode = LOGMODE_BOTH;
106 if (rc < 0)
107 bb_error_msg_and_die("an error occurred updating password for %s", name);
108 if (rc)
109 bb_info_msg("password for '%s' changed", name);
110 logmode = LOGMODE_STDIO;
111 free(name);
112 free(free_me);
113 }
114 return EXIT_SUCCESS;
115}
116