diff options
Diffstat (limited to 'loginutils/passwd.c')
-rw-r--r-- | loginutils/passwd.c | 75 |
1 files changed, 37 insertions, 38 deletions
diff --git a/loginutils/passwd.c b/loginutils/passwd.c index 810644e..8c47e65 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c @@ -9,7 +9,7 @@ //usage: "Change USER's password. If no USER is specified,\n" //usage: "changes the password for the current user.\n" //usage: "\nOptions:" -//usage: "\n -a ALG Algorithm to use for password (des, md5)" /* ", sha1)" */ +//usage: "\n -a ALG Encryption method" //usage: "\n -d Delete password for the account" //usage: "\n -l Lock (disable) account" //usage: "\n -u Unlock (re-enable) account" @@ -22,15 +22,15 @@ static void nuke_str(char *str) if (str) memset(str, 0, strlen(str)); } -static char* new_password(const struct passwd *pw, uid_t myuid, int algo) +static char* new_password(const struct passwd *pw, uid_t myuid, const char *algo) { - char salt[sizeof("$N$XXXXXXXX")]; /* "$N$XXXXXXXX" or "XX" */ + char salt[MAX_PW_SALT_LEN]; char *orig = (char*)""; char *newp = NULL; char *cp = NULL; char *ret = NULL; /* failure so far */ - if (myuid && pw->pw_passwd[0]) { + if (myuid != 0 && pw->pw_passwd[0]) { char *encrypted; orig = bb_ask_stdin("Old password: "); /* returns ptr to static */ @@ -38,13 +38,13 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo) goto err_ret; encrypted = pw_encrypt(orig, pw->pw_passwd, 1); /* returns malloced str */ if (strcmp(encrypted, pw->pw_passwd) != 0) { - syslog(LOG_WARNING, "incorrect password for %s", - pw->pw_name); + syslog(LOG_WARNING, "incorrect password for %s", pw->pw_name); bb_do_delay(LOGIN_FAIL_DELAY); puts("Incorrect password"); goto err_ret; } - if (ENABLE_FEATURE_CLEAN_UP) free(encrypted); + if (ENABLE_FEATURE_CLEAN_UP) + free(encrypted); } orig = xstrdup(orig); /* or else bb_ask_stdin() will destroy it */ newp = bb_ask_stdin("New password: "); /* returns ptr to static */ @@ -52,22 +52,22 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo) goto err_ret; newp = xstrdup(newp); /* we are going to bb_ask_stdin() again, so save it */ if (ENABLE_FEATURE_PASSWD_WEAK_CHECK - && obscure(orig, newp, pw) && myuid) + && obscure(orig, newp, pw) + && myuid != 0 + ) { goto err_ret; /* non-root is not allowed to have weak passwd */ + } cp = bb_ask_stdin("Retype password: "); if (!cp) goto err_ret; - if (strcmp(cp, newp)) { + if (strcmp(cp, newp) != 0) { puts("Passwords don't match"); goto err_ret; } - crypt_make_salt(salt, 1, 0); /* des */ - if (algo) { /* MD5 */ - strcpy(salt, "$1$"); - crypt_make_salt(salt + 3, 4, 0); - } + crypt_make_pw_salt(salt, algo); + /* pw_encrypt returns malloced str */ ret = pw_encrypt(newp, salt, 1); /* whee, success! */ @@ -75,8 +75,10 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo) err_ret: nuke_str(orig); if (ENABLE_FEATURE_CLEAN_UP) free(orig); + nuke_str(newp); if (ENABLE_FEATURE_CLEAN_UP) free(newp); + nuke_str(cp); return ret; } @@ -85,17 +87,15 @@ int passwd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int passwd_main(int argc UNUSED_PARAM, char **argv) { enum { - OPT_algo = 0x1, /* -a - password algorithm */ - OPT_lock = 0x2, /* -l - lock account */ - OPT_unlock = 0x4, /* -u - unlock account */ - OPT_delete = 0x8, /* -d - delete password */ - OPT_lud = 0xe, - STATE_ALGO_md5 = 0x10, - //STATE_ALGO_des = 0x20, not needed yet + OPT_algo = (1 << 0), /* -a - password algorithm */ + OPT_lock = (1 << 1), /* -l - lock account */ + OPT_unlock = (1 << 2), /* -u - unlock account */ + OPT_delete = (1 << 3), /* -d - delete password */ + OPT_lud = OPT_lock | OPT_unlock | OPT_delete, }; unsigned opt; int rc; - const char *opt_a = ""; + const char *opt_a = "d"; /* des */ const char *filename; char *myname; char *name; @@ -116,13 +116,9 @@ int passwd_main(int argc UNUSED_PARAM, char **argv) //argc -= optind; argv += optind; - if (strcasecmp(opt_a, "des") != 0) /* -a */ - opt |= STATE_ALGO_md5; - //else - // opt |= STATE_ALGO_des; myuid = getuid(); /* -l, -u, -d require root priv and username argument */ - if ((opt & OPT_lud) && (myuid || !argv[0])) + if ((opt & OPT_lud) && (myuid != 0 || !argv[0])) bb_show_usage(); /* Will complain and die if username not found */ @@ -130,7 +126,7 @@ int passwd_main(int argc UNUSED_PARAM, char **argv) name = argv[0] ? argv[0] : myname; pw = xgetpwnam(name); - if (myuid && pw->pw_uid != myuid) { + if (myuid != 0 && pw->pw_uid != myuid) { /* LOGMODE_BOTH */ bb_error_msg_and_die("%s can't change password for %s", myname, name); } @@ -164,27 +160,29 @@ int passwd_main(int argc UNUSED_PARAM, char **argv) newp = NULL; c = pw->pw_passwd[0] - '!'; if (!(opt & OPT_lud)) { - if (myuid && !c) { /* passwd starts with '!' */ + if (myuid != 0 && !c) { /* passwd starts with '!' */ /* LOGMODE_BOTH */ bb_error_msg_and_die("can't change " "locked password for %s", name); } printf("Changing password for %s\n", name); - newp = new_password(pw, myuid, opt & STATE_ALGO_md5); + newp = new_password(pw, myuid, opt_a); if (!newp) { logmode = LOGMODE_STDIO; bb_error_msg_and_die("password for %s is unchanged", name); } } else if (opt & OPT_lock) { - if (!c) goto skip; /* passwd starts with '!' */ + if (!c) + goto skip; /* passwd starts with '!' */ newp = xasprintf("!%s", pw->pw_passwd); } else if (opt & OPT_unlock) { - if (c) goto skip; /* not '!' */ + if (c) + goto skip; /* not '!' */ /* pw->pw_passwd points to static storage, * strdup'ing to avoid nasty surprizes */ newp = xstrdup(&pw->pw_passwd[1]); } else if (opt & OPT_delete) { - newp = (char*)""; //xstrdup(""); + newp = (char*)""; } rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * 30000; @@ -202,7 +200,7 @@ int passwd_main(int argc UNUSED_PARAM, char **argv) rc = update_passwd(bb_path_shadow_file, name, newp, NULL); if (rc > 0) /* password in /etc/shadow was updated */ - newp = (char*) "x"; //xstrdup("x"); + newp = (char*) "x"; if (rc >= 0) /* 0 = /etc/shadow missing (not an error), >0 = passwd changed in /etc/shadow */ #endif @@ -212,16 +210,17 @@ int passwd_main(int argc UNUSED_PARAM, char **argv) } /* LOGMODE_BOTH */ if (rc < 0) - bb_error_msg_and_die("can't update password file %s", - filename); + bb_error_msg_and_die("can't update password file %s", filename); bb_info_msg("Password for %s changed by %s", name, myname); - //if (ENABLE_FEATURE_CLEAN_UP) free(newp); + /*if (ENABLE_FEATURE_CLEAN_UP) free(newp); - can't, it may be non-malloced */ skip: if (!newp) { bb_error_msg_and_die("password for %s is already %slocked", name, (opt & OPT_unlock) ? "un" : ""); } - if (ENABLE_FEATURE_CLEAN_UP) free(myname); + + if (ENABLE_FEATURE_CLEAN_UP) + free(myname); return 0; } |