2 |
/* |
/* |
3 |
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
4 |
*/ |
*/ |
|
|
|
5 |
#include "libbb.h" |
#include "libbb.h" |
6 |
#include <syslog.h> |
#include <syslog.h> |
7 |
|
|
21 |
if (myuid && pw->pw_passwd[0]) { |
if (myuid && pw->pw_passwd[0]) { |
22 |
char *encrypted; |
char *encrypted; |
23 |
|
|
24 |
orig = bb_askpass(0, "Old password:"); /* returns ptr to static */ |
orig = bb_ask_stdin("Old password: "); /* returns ptr to static */ |
25 |
if (!orig) |
if (!orig) |
26 |
goto err_ret; |
goto err_ret; |
27 |
encrypted = pw_encrypt(orig, pw->pw_passwd, 1); /* returns malloced str */ |
encrypted = pw_encrypt(orig, pw->pw_passwd, 1); /* returns malloced str */ |
34 |
} |
} |
35 |
if (ENABLE_FEATURE_CLEAN_UP) free(encrypted); |
if (ENABLE_FEATURE_CLEAN_UP) free(encrypted); |
36 |
} |
} |
37 |
orig = xstrdup(orig); /* or else bb_askpass() will destroy it */ |
orig = xstrdup(orig); /* or else bb_ask_stdin() will destroy it */ |
38 |
newp = bb_askpass(0, "New password:"); /* returns ptr to static */ |
newp = bb_ask_stdin("New password: "); /* returns ptr to static */ |
39 |
if (!newp) |
if (!newp) |
40 |
goto err_ret; |
goto err_ret; |
41 |
newp = xstrdup(newp); /* we are going to bb_askpass() again, so save it */ |
newp = xstrdup(newp); /* we are going to bb_ask_stdin() again, so save it */ |
42 |
if (ENABLE_FEATURE_PASSWD_WEAK_CHECK |
if (ENABLE_FEATURE_PASSWD_WEAK_CHECK |
43 |
&& obscure(orig, newp, pw) && myuid) |
&& obscure(orig, newp, pw) && myuid) |
44 |
goto err_ret; /* non-root is not allowed to have weak passwd */ |
goto err_ret; /* non-root is not allowed to have weak passwd */ |
45 |
|
|
46 |
cp = bb_askpass(0, "Retype password:"); |
cp = bb_ask_stdin("Retype password: "); |
47 |
if (!cp) |
if (!cp) |
48 |
goto err_ret; |
goto err_ret; |
49 |
if (strcmp(cp, newp)) { |
if (strcmp(cp, newp)) { |
99 |
#endif |
#endif |
100 |
|
|
101 |
logmode = LOGMODE_BOTH; |
logmode = LOGMODE_BOTH; |
102 |
openlog(applet_name, LOG_NOWAIT, LOG_AUTH); |
openlog(applet_name, 0, LOG_AUTH); |
103 |
opt = getopt32(argv, "a:lud", &opt_a); |
opt = getopt32(argv, "a:lud", &opt_a); |
104 |
//argc -= optind; |
//argc -= optind; |
105 |
argv += optind; |
argv += optind; |
114 |
bb_show_usage(); |
bb_show_usage(); |
115 |
|
|
116 |
/* Will complain and die if username not found */ |
/* Will complain and die if username not found */ |
117 |
myname = xstrdup(bb_getpwuid(NULL, -1, myuid)); |
myname = xstrdup(xuid2uname(myuid)); |
118 |
name = argv[0] ? argv[0] : myname; |
name = argv[0] ? argv[0] : myname; |
119 |
|
|
120 |
pw = getpwnam(name); |
pw = xgetpwnam(name); |
|
if (!pw) |
|
|
bb_error_msg_and_die("unknown user %s", name); |
|
121 |
if (myuid && pw->pw_uid != myuid) { |
if (myuid && pw->pw_uid != myuid) { |
122 |
/* LOGMODE_BOTH */ |
/* LOGMODE_BOTH */ |
123 |
bb_error_msg_and_die("%s can't change password for %s", myname, name); |
bb_error_msg_and_die("%s can't change password for %s", myname, name); |
128 |
/* getspnam_r may return 0 yet set result to NULL. |
/* getspnam_r may return 0 yet set result to NULL. |
129 |
* At least glibc 2.4 does this. Be extra paranoid here. */ |
* At least glibc 2.4 does this. Be extra paranoid here. */ |
130 |
struct spwd *result = NULL; |
struct spwd *result = NULL; |
131 |
if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result) |
errno = 0; |
132 |
|| !result || strcmp(result->sp_namp, pw->pw_name) != 0) { |
if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result) != 0 |
133 |
/* LOGMODE_BOTH */ |
|| !result /* no error, but no record found either */ |
134 |
bb_error_msg("no record of %s in %s, using %s", |
|| strcmp(result->sp_namp, pw->pw_name) != 0 /* paranoia */ |
135 |
|
) { |
136 |
|
if (errno != ENOENT) { |
137 |
|
/* LOGMODE_BOTH */ |
138 |
|
bb_perror_msg("no record of %s in %s, using %s", |
139 |
name, bb_path_shadow_file, |
name, bb_path_shadow_file, |
140 |
bb_path_passwd_file); |
bb_path_passwd_file); |
141 |
|
} |
142 |
|
/* else: /etc/shadow does not exist, |
143 |
|
* apparently we are on a shadow-less system, |
144 |
|
* no surprise there */ |
145 |
} else { |
} else { |
146 |
pw->pw_passwd = result->sp_pwdp; |
pw->pw_passwd = result->sp_pwdp; |
147 |
} |
} |
154 |
if (!(opt & OPT_lud)) { |
if (!(opt & OPT_lud)) { |
155 |
if (myuid && !c) { /* passwd starts with '!' */ |
if (myuid && !c) { /* passwd starts with '!' */ |
156 |
/* LOGMODE_BOTH */ |
/* LOGMODE_BOTH */ |
157 |
bb_error_msg_and_die("cannot change " |
bb_error_msg_and_die("can't change " |
158 |
"locked password for %s", name); |
"locked password for %s", name); |
159 |
} |
} |
160 |
printf("Changing password for %s\n", name); |
printf("Changing password for %s\n", name); |
188 |
|
|
189 |
#if ENABLE_FEATURE_SHADOWPASSWDS |
#if ENABLE_FEATURE_SHADOWPASSWDS |
190 |
filename = bb_path_shadow_file; |
filename = bb_path_shadow_file; |
191 |
rc = update_passwd(bb_path_shadow_file, name, newp); |
rc = update_passwd(bb_path_shadow_file, name, newp, NULL); |
192 |
if (rc == 0) /* no lines updated, no errors detected */ |
if (rc == 0) /* no lines updated, no errors detected */ |
193 |
#endif |
#endif |
194 |
{ |
{ |
195 |
filename = bb_path_passwd_file; |
filename = bb_path_passwd_file; |
196 |
rc = update_passwd(bb_path_passwd_file, name, newp); |
rc = update_passwd(bb_path_passwd_file, name, newp, NULL); |
197 |
} |
} |
198 |
/* LOGMODE_BOTH */ |
/* LOGMODE_BOTH */ |
199 |
if (rc < 0) |
if (rc < 0) |
200 |
bb_error_msg_and_die("cannot update password file %s", |
bb_error_msg_and_die("can't update password file %s", |
201 |
filename); |
filename); |
202 |
bb_info_msg("Password for %s changed by %s", name, myname); |
bb_info_msg("Password for %s changed by %s", name, myname); |
203 |
|
|