int main(int argc, char **argv) { struct passwd *pw; char user[64], password[64], crypted[64]; char *cp; if (argc != 2) { printf("Usage: passwd <user>\n"); return 1; } strcpy(user, argv[1]); if ((pw = getpwnam(user)) == NULL) { printf("No such user.\n"); return 1; } if (strcmp(pw->pw_passwd, "*")) { strcpy(password, getpass("Old password:"******"Incorrect password.\n"); return 1; } } strcpy(password, getpass("New password:"******"Re-type new password:"******"New passwords don't match.\n"); return 1; } strcpy(crypted, crypt(password, SALT)); if (strcmp(pw->pw_passwd, crypted) == 0) { printf("Password unchanged.\n"); return 1; } if (setpwnam(user, crypted)) { printf("Update of passwd file failed.\n"); return 1; } printf("Password changed.\n"); return 0; }
int main(int argc, char *argv[]) { struct passwd *pe; uid_t gotuid = getuid(); char *pwdstr = NULL, *cryptstr, *oldstr; char pwdstr1[10]; char *user; time_t tm; char salt[2]; int force_passwd = 0; int silent = 0; int c; int opt_index; int fullname = 0, shell = 0; static const struct option long_options[] = { {"fullname", no_argument, 0, 'f'}, {"shell", no_argument, 0, 's'}, {"force", no_argument, 0, 'o'}, {"quiet", no_argument, 0, 'q'}, {"silent", no_argument, 0, 'q'}, {"version", no_argument, 0, 'v'}, {0, 0, 0, 0} }; sanitize_env(); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); optind = 0; while ((c = getopt_long(argc, argv, "foqsvV", long_options, &opt_index)) != -1) { switch (c) { case 'f': fullname = 1; break; case 's': shell = 1; break; case 'o': force_passwd = 1; break; case 'q': silent = 1; break; case 'V': case 'v': printf("%s\n", util_linux_version); exit(0); default: fprintf(stderr, _("Usage: passwd [-foqsvV] [user [password]]\n")); exit(1); } /* switch (c) */ } /* while */ if (fullname || shell) { char *args[100]; int i, j, errsv; setuid(getuid()); /* drop special privs. */ if (fullname) args[0] = _PATH_CHFN; else args[0] = _PATH_CHSH; for (i = optind, j = 1; (i < argc) && (j < 99); i++, j++) args[j] = argv[i]; args[j] = NULL; execv(args[0], args); errsv = errno; fprintf(stderr, _("Can't exec %s: %s\n"), args[0], strerror(errsv)); exit(1); } switch (argc - optind) { case 0: /* Why use getlogin()? Some systems allow having several usernames with the same uid, especially several root accounts. One changes the password for the username, not the uid. */ if ( !(user = getlogin()) || !*user ) { if ( !(pe = getpwuid( getuid() )) ) { pexit(_("Cannot find login name")); } else user = pe->pw_name; } break; case 1: if(gotuid) { printf(_("Only root can change the password for others.\n")); exit (1); } else user = argv[optind]; break; case 2: if(gotuid) { printf(_("Only root can change the password for others.\n")); exit(1); } else { user = argv[optind]; pwdstr = argv[optind+1]; } break; default: printf(_("Too many arguments.\n")); exit (1); } /* switch */ if(!(pe = getpwnam(user))) { pexit(_("Can't find username anywhere. Is `%s' really a user?"), user); } if (!(is_local(user))) { puts(_("Sorry, I can only change local passwords. Use yppasswd instead.")); exit(1); } /* if somebody got into changing utmp... */ if(gotuid && gotuid != pe->pw_uid) { puts(_("UID and username does not match, imposter!")); exit(1); } if ( !silent ) printf( _("Changing password for %s\n"), user ); if ( (gotuid && pe->pw_passwd && pe->pw_passwd[0]) || (!gotuid && !strcmp(user,"root")) ) { oldstr = getpass(_("Enter old password: "******"Illegal password, imposter.")); exit(1); } } if ( pwdstr ) { /* already set on command line */ if ( !force_passwd && !check_passwd(pwdstr, pe->pw_passwd, user, pe->pw_gecos) ) exit (1); } else { /* password not set on command line by root, ask for it ... */ redo_it: pwdstr = getpass(_("Enter new password: "******"Password not changed.")); exit(1); } if ( (gotuid || (!gotuid && !force_passwd)) && !check_passwd(pwdstr, pe->pw_passwd, user, pe->pw_gecos) ) goto redo_it; xstrncpy(pwdstr1, pwdstr, sizeof(pwdstr1)); pwdstr = getpass(_("Re-type new password: "******"You misspelled it. Password not changed.")); exit(1); } } /* pwdstr i.e. password set on command line */ time(&tm); tm ^= getpid(); salt[0] = bin_to_ascii(tm & 0x3f); salt[1] = bin_to_ascii((tm >> 6) & 0x3f); cryptstr = crypt(pwdstr, salt); if (pwdstr[0] == 0) cryptstr = ""; #ifdef LOGALL openlog("passwd", 0, LOG_AUTH); if (gotuid) syslog(LOG_NOTICE,_("password changed, user %s"),user); else { if ( !strcmp(user, "root") ) syslog(LOG_WARNING,_("ROOT PASSWORD CHANGED")); else syslog(LOG_NOTICE,_("password changed by root, user %s"),user); } closelog(); #endif /* LOGALL */ pe->pw_passwd = cryptstr; #ifdef DEBUG printf (_("calling setpwnam to set password.\n")); #else if (setpwnam( pe ) < 0) { perror( "setpwnam" ); printf( _("Password *NOT* changed. Try again later.\n" )); exit( 1 ); } #endif if ( !silent ) printf(_("Password changed.\n")); exit(0); }