31 |
#include "libbb.h" |
#include "libbb.h" |
32 |
|
|
33 |
/* Ask the user for a password. |
/* Ask the user for a password. |
34 |
Return 1 if the user gives the correct password for entry PW, |
* Return 1 if the user gives the correct password for entry PW, |
35 |
0 if not. Return 1 without asking for a password if run by UID 0 |
* 0 if not. Return 1 without asking if PW has an empty password. |
36 |
or if PW has an empty password. */ |
* |
37 |
|
* NULL pw means "just fake it for login with bad username" */ |
38 |
|
|
39 |
int correct_password(const struct passwd *pw) |
int FAST_FUNC correct_password(const struct passwd *pw) |
40 |
{ |
{ |
41 |
char *unencrypted, *encrypted, *correct; |
char *unencrypted, *encrypted; |
42 |
|
const char *correct; |
43 |
#ifdef CONFIG_FEATURE_SHADOWPASSWDS |
int r; |
44 |
if (LONE_CHAR(pw->pw_passwd, 'x') || LONE_CHAR(pw->pw_passwd, '*')) { |
#if ENABLE_FEATURE_SHADOWPASSWDS |
45 |
struct spwd *sp = getspnam(pw->pw_name); |
/* Using _r function to avoid pulling in static buffers */ |
46 |
|
struct spwd spw; |
47 |
if (!sp) |
char buffer[256]; |
48 |
bb_error_msg_and_die("no valid shadow password"); |
#endif |
49 |
|
|
50 |
correct = sp->sp_pwdp; |
/* fake salt. crypt() can choke otherwise. */ |
51 |
} else |
correct = "aa"; |
52 |
|
if (!pw) { |
53 |
|
/* "aa" will never match */ |
54 |
|
goto fake_it; |
55 |
|
} |
56 |
|
correct = pw->pw_passwd; |
57 |
|
#if ENABLE_FEATURE_SHADOWPASSWDS |
58 |
|
if ((correct[0] == 'x' || correct[0] == '*') && !correct[1]) { |
59 |
|
/* getspnam_r may return 0 yet set result to NULL. |
60 |
|
* At least glibc 2.4 does this. Be extra paranoid here. */ |
61 |
|
struct spwd *result = NULL; |
62 |
|
r = getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result); |
63 |
|
correct = (r || !result) ? "aa" : result->sp_pwdp; |
64 |
|
} |
65 |
#endif |
#endif |
|
correct = pw->pw_passwd; |
|
66 |
|
|
67 |
if (!correct || correct[0] == '\0') |
if (!correct[0]) /* empty password field? */ |
68 |
return 1; |
return 1; |
69 |
|
|
70 |
|
fake_it: |
71 |
unencrypted = bb_askpass(0, "Password: "); |
unencrypted = bb_askpass(0, "Password: "); |
72 |
if (!unencrypted) { |
if (!unencrypted) { |
73 |
return 0; |
return 0; |
74 |
} |
} |
75 |
encrypted = crypt(unencrypted, correct); |
encrypted = pw_encrypt(unencrypted, correct, 1); |
76 |
|
r = (strcmp(encrypted, correct) == 0); |
77 |
|
free(encrypted); |
78 |
memset(unencrypted, 0, strlen(unencrypted)); |
memset(unencrypted, 0, strlen(unencrypted)); |
79 |
return (!strcmp(encrypted, correct)) ? 1 : 0; |
return r; |
80 |
} |
} |