X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=loginutils%2Fpasswd.c;h=aa75dd260fa73cc6db133391592de84051216f7e;hb=d25a2645f5273e70616abe73e6ac1adda5016532;hp=d0b2afc19bae19de173306d5e45abe5b90b2c8ba;hpb=6f9a7783ce2f3ffae28176f8bcfcd6b86c1b41b3;p=oweals%2Fbusybox.git diff --git a/loginutils/passwd.c b/loginutils/passwd.c index d0b2afc19..aa75dd260 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c @@ -1,18 +1,10 @@ /* vi: set sw=4 ts=4: */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +/* + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ #include "busybox.h" +#include static char crypt_passwd[128]; @@ -21,7 +13,7 @@ static int new_password(const struct passwd *pw, int amroot, int algo); static void set_filesize_limit(int blocks); -int get_algo(char *a) +static int get_algo(char *a) { int x = 1; /* standard: MD5 */ @@ -31,14 +23,13 @@ int get_algo(char *a) } -extern int update_passwd(const struct passwd *pw, char *crypt_pw) +static int update_passwd(const struct passwd *pw, const char *crypt_pw) { char filename[1024]; char buf[1025]; char buffer[80]; char username[32]; char *pw_rest; - int has_shadow = 0; int mask; int continued; FILE *fp; @@ -46,12 +37,12 @@ extern int update_passwd(const struct passwd *pw, char *crypt_pw) struct stat sb; struct flock lock; +#if ENABLE_FEATURE_SHADOWPASSWDS if (access(bb_path_shadow_file, F_OK) == 0) { - has_shadow = 1; - } - if (has_shadow) { snprintf(filename, sizeof filename, "%s", bb_path_shadow_file); - } else { + } else +#endif + { snprintf(filename, sizeof filename, "%s", bb_path_passwd_file); } @@ -94,8 +85,9 @@ extern int update_passwd(const struct passwd *pw, char *crypt_pw) rewind(fp); while (!feof(fp)) { fgets(buffer, sizeof buffer, fp); - if (!continued) { // Check to see if we're updating this line. - if (strncmp(username, buffer, strlen(username)) == 0) { // we have a match. + if (!continued) { /* Check to see if we're updating this line. */ + if (strncmp(username, buffer, strlen(username)) == 0) { + /* we have a match. */ pw_rest = strchr(buffer, ':'); *pw_rest++ = '\0'; pw_rest = strchr(pw_rest, ':'); @@ -111,7 +103,7 @@ extern int update_passwd(const struct passwd *pw, char *crypt_pw) } else { continued = 1; } - bzero(buffer, sizeof buffer); + memset(buffer, 0, sizeof buffer); } if (fflush(out_fp) || fsync(fileno(out_fp)) || fclose(out_fp)) { @@ -132,7 +124,7 @@ extern int update_passwd(const struct passwd *pw, char *crypt_pw) } -extern int passwd_main(int argc, char **argv) +int passwd_main(int argc, char **argv) { int amroot; char *cp; @@ -145,11 +137,7 @@ extern int passwd_main(int argc, char **argv) int uflg = 0; /* -u - unlock account */ int dflg = 0; /* -d - delete password */ const struct passwd *pw; - unsigned short ruid; -#ifdef CONFIG_FEATURE_SHADOWPASSWDS - const struct spwd *sp; -#endif /* CONFIG_FEATURE_SHADOWPASSWDS */ amroot = (getuid() == 0); openlog("passwd", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH); while ((flag = getopt(argc, argv, "a:dlu")) != EOF) { @@ -170,12 +158,8 @@ extern int passwd_main(int argc, char **argv) bb_show_usage(); } } - ruid = getuid(); - pw = (struct passwd *) getpwuid(ruid); - if (!pw) { - bb_error_msg_and_die("Cannot determine your user name."); - } - myname = (char *) bb_xstrdup(pw->pw_name); + myname = (char *) xstrdup(bb_getpwuid(NULL, getuid(), -1)); + /* exits on error */ if (optind < argc) { name = argv[optind]; } else { @@ -192,18 +176,13 @@ extern int passwd_main(int argc, char **argv) syslog(LOG_WARNING, "can't change pwd for `%s'", name); bb_error_msg_and_die("Permission denied.\n"); } -#ifdef CONFIG_FEATURE_SHADOWPASSWDS - sp = getspnam(name); - if (!sp) { - sp = (struct spwd *) pwd_to_spwd(pw); - } - cp = sp->sp_pwdp; - np = sp->sp_namp; -#else - cp = pw->pw_passwd; - np = name; -#endif /* CONFIG_FEATURE_SHADOWPASSWDS */ + if (ENABLE_FEATURE_SHADOWPASSWDS) { + struct spwd *sp = getspnam(name); + if (!sp) bb_error_msg_and_die("Unknown user %s", name); + cp = sp->sp_pwdp; + } else cp = pw->pw_passwd; + np = name; safe_strncpy(crypt_passwd, cp, sizeof(crypt_passwd)); if (!(dflg || lflg || uflg)) { if (!amroot) { @@ -236,10 +215,7 @@ extern int passwd_main(int argc, char **argv) signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); umask(077); - if (setuid(0)) { - syslog(LOG_ERR, "can't setuid(0)"); - bb_error_msg_and_die( "Cannot change ID to root.\n"); - } + xsetuid(0); if (!update_passwd(pw, crypt_passwd)) { syslog(LOG_INFO, "password for `%s' changed by user `%s'", name, myname); @@ -248,6 +224,7 @@ extern int passwd_main(int argc, char **argv) syslog(LOG_WARNING, "an error occurred updating the password file"); bb_error_msg_and_die("An error occurred updating the password file.\n"); } + if (ENABLE_FEATURE_CLEAN_UP) free(myname); return (0); } @@ -327,9 +304,9 @@ static int new_password(const struct passwd *pw, int amroot, int algo) char *clear; char *cipher; char *cp; + char salt[12]; /* "$N$XXXXXXXX" or "XX" */ char orig[200]; char pass[200]; - time_t start, now; if (!amroot && crypt_passwd[0]) { if (!(clear = bb_askpass(0, "Old password:"))) { @@ -340,19 +317,14 @@ static int new_password(const struct passwd *pw, int amroot, int algo) if (strcmp(cipher, crypt_passwd) != 0) { syslog(LOG_WARNING, "incorrect password for `%s'", pw->pw_name); - time(&start); - now = start; - while (difftime(now, start) < FAIL_DELAY) { - sleep(FAIL_DELAY); - time(&now); - } + bb_do_delay(FAIL_DELAY); fprintf(stderr, "Incorrect password.\n"); /* return -1; */ return 1; } safe_strncpy(orig, clear, sizeof(orig)); - bzero(clear, strlen(clear)); - bzero(cipher, strlen(cipher)); + memset(clear, 0, strlen(clear)); + memset(cipher, 0, strlen(cipher)); } else { orig[0] = '\0'; } @@ -360,12 +332,12 @@ static int new_password(const struct passwd *pw, int amroot, int algo) "Please use a combination of upper and lower case letters and numbers.\n" "Enter new password: "))) { - bzero(orig, sizeof orig); + memset(orig, 0, sizeof orig); /* return -1; */ return 1; } safe_strncpy(pass, cp, sizeof(pass)); - bzero(cp, strlen(cp)); + memset(cp, 0, strlen(cp)); /* if (!obscure(orig, pass, pw)) { */ if (obscure(orig, pass, pw)) { if (amroot) { @@ -376,7 +348,7 @@ static int new_password(const struct passwd *pw, int amroot, int algo) } } if (!(cp = bb_askpass(0, "Re-enter new password: "))) { - bzero(orig, sizeof orig); + memset(orig, 0, sizeof orig); /* return -1; */ return 1; } @@ -385,14 +357,21 @@ static int new_password(const struct passwd *pw, int amroot, int algo) /* return -1; */ return 1; } - bzero(cp, strlen(cp)); - bzero(orig, sizeof(orig)); + memset(cp, 0, strlen(cp)); + memset(orig, 0, sizeof(orig)); + memset(salt, 0, sizeof(salt)); if (algo == 1) { - cp = pw_encrypt(pass, "$1$"); - } else - cp = pw_encrypt(pass, crypt_make_salt()); - bzero(pass, sizeof pass); + strcpy(salt, "$1$"); + strcat(salt, crypt_make_salt()); + strcat(salt, crypt_make_salt()); + strcat(salt, crypt_make_salt()); + } + + strcat(salt, crypt_make_salt()); + cp = pw_encrypt(pass, salt); + + memset(pass, 0, sizeof pass); safe_strncpy(crypt_passwd, cp, sizeof(crypt_passwd)); return 0; }