X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=loginutils%2Fpasswd.c;h=aa75dd260fa73cc6db133391592de84051216f7e;hb=d25a2645f5273e70616abe73e6ac1adda5016532;hp=9c84c167c350e3221d7765548698063947ac6f6c;hpb=27f64e1f4eb4354844f6553e37501deffde8373e;p=oweals%2Fbusybox.git diff --git a/loginutils/passwd.c b/loginutils/passwd.c index 9c84c167c..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,24 +13,23 @@ 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 = 0; /* standart: DES */ + int x = 1; /* standard: MD5 */ - if (strcasecmp(a, "md5") == 0) - x = 1; + if (strcasecmp(a, "des") == 0) + x = 0; return x; } -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,13 +37,13 @@ extern int update_passwd(const struct passwd *pw, char *crypt_pw) struct stat sb; struct flock lock; - if (access(shadow_file, F_OK) == 0) { - has_shadow = 1; - } - if (has_shadow) { - snprintf(filename, sizeof filename, "%s", shadow_file); - } else { - snprintf(filename, sizeof filename, "%s", passwd_file); +#if ENABLE_FEATURE_SHADOWPASSWDS + if (access(bb_path_shadow_file, F_OK) == 0) { + snprintf(filename, sizeof filename, "%s", bb_path_shadow_file); + } else +#endif + { + snprintf(filename, sizeof filename, "%s", bb_path_passwd_file); } if (((fp = fopen(filename, "r+")) == 0) || (fstat(fileno(fp), &sb))) { @@ -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; @@ -140,16 +132,12 @@ extern int passwd_main(int argc, char **argv) char *name; char *myname; int flag; - int algo = 0; /* -a - password algorithm */ + int algo = 1; /* -a - password algorithm */ int lflg = 0; /* -l - lock account */ 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) { @@ -167,54 +155,45 @@ extern int passwd_main(int argc, char **argv) uflg++; break; default: - show_usage(); + bb_show_usage(); } } - ruid = getuid(); - pw = (struct passwd *) getpwuid(ruid); - if (!pw) { - error_msg_and_die("Cannot determine your user name.\n"); - } - myname = (char *) xstrdup(pw->pw_name); + myname = (char *) xstrdup(bb_getpwuid(NULL, getuid(), -1)); + /* exits on error */ if (optind < argc) { name = argv[optind]; } else { name = myname; } if ((lflg || uflg || dflg) && (optind >= argc || !amroot)) { - show_usage(); + bb_show_usage(); } pw = getpwnam(name); if (!pw) { - error_msg_and_die("Unknown user %s\n", name); + bb_error_msg_and_die("Unknown user %s\n", name); } if (!amroot && pw->pw_uid != getuid()) { syslog(LOG_WARNING, "can't change pwd for `%s'", name); - error_msg_and_die("Permission denied.\n"); - } -#ifdef CONFIG_FEATURE_SHADOWPASSWDS - sp = getspnam(name); - if (!sp) { - sp = (struct spwd *) pwd_to_spwd(pw); + bb_error_msg_and_die("Permission denied.\n"); } - 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) { if (cp[0] == '!') { syslog(LOG_WARNING, "password locked for `%s'", np); - error_msg_and_die( "The password for `%s' cannot be changed.\n", np); + bb_error_msg_and_die( "The password for `%s' cannot be changed.\n", np); } } printf("Changing password for %s\n", name); if (new_password(pw, amroot, algo)) { - error_msg_and_die( "The password for %s is unchanged.\n", name); + bb_error_msg_and_die( "The password for %s is unchanged.\n", name); } } else if (lflg) { if (crypt_passwd[0] != '!') { @@ -236,19 +215,16 @@ 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)"); - 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); printf("Password changed.\n"); } else { - syslog(LOG_WARNING, - "an error occurred updating the password file"); - error_msg_and_die("An error occurred updating the password file.\n"); + 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); } @@ -328,12 +304,12 @@ 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 = getpass("Old password:"))) { + if (!(clear = bb_askpass(0, "Old password:"))) { /* return -1; */ return 1; } @@ -341,33 +317,27 @@ 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'; } - if (! - (cp = - getpass ("Enter the new password (minimum of 5, maximum of 8 characters)\n"" - Please use a combination of upper and lower case letters and numbers.\nEnter new password: "))) + if (! (cp=bb_askpass(0, "Enter the new password (minimum of 5, maximum of 8 characters)\n" + "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) { @@ -377,8 +347,8 @@ static int new_password(const struct passwd *pw, int amroot, int algo) return 1; } } - if (!(cp = getpass("Re-enter new password: "))) { - bzero(orig, sizeof orig); + if (!(cp = bb_askpass(0, "Re-enter new password: "))) { + memset(orig, 0, sizeof orig); /* return -1; */ return 1; } @@ -387,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; }