Sflg = false, /* -S - show password status */
uflg = false, /* -u - unlock the user's password */
wflg = false, /* -w - set warning days */
- xflg = false; /* -x - set maximum days */
+ xflg = false, /* -x - set maximum days */
+ sflg = false; /* -s - read passwd from stdin */
/*
* set to 1 if there are any flags which require root privileges,
(void) fputs (_(" -w, --warndays WARN_DAYS set expiration warning days to WARN_DAYS\n"), usageout);
(void) fputs (_(" -x, --maxdays MAX_DAYS set maximum number of days before password\n"
" change to MAX_DAYS\n"), usageout);
+ (void) fputs (_(" -s, --stdin read new token from stdin\n"), usageout);
(void) fputs ("\n", usageout);
exit (status);
}
pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
}
}
- if (!qflg) {
+ if (!qflg && !sflg) {
if (pass_max_len == -1) {
(void) printf (_(
"Enter the new password (minimum of %d characters)\n"
}
}
- warned = false;
- for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) {
- cp = agetpass (_("New password: "));
+ if (sflg) {
+ /*
+ * root is setting the passphrase from stdin
+ */
+ cp = agetpass_stdin ();
if (NULL == cp) {
- MEMZERO(orig);
- MEMZERO(pass);
return -1;
}
- if (warned && (strcmp (pass, cp) != 0)) {
- warned = false;
- }
- STRTCPY(pass, cp);
+ STRTCPY (pass, cp);
erase_pass (cp);
+ } else {
+ warned = false;
+ for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) {
+ cp = agetpass (_("New password: "));
+ if (NULL == cp) {
+ MEMZERO(orig);
+ MEMZERO(pass);
+ return -1;
+ }
+ if (warned && (strcmp (pass, cp) != 0)) {
+ warned = false;
+ }
+ STRTCPY(pass, cp);
+ erase_pass (cp);
- if (!amroot && !obscure(orig, pass, pw)) {
- (void) puts (_("Try again."));
- continue;
- }
+ if (!amroot && !obscure(orig, pass, pw)) {
+ (void) puts (_("Try again."));
+ continue;
+ }
- /*
- * If enabled, warn about weak passwords even if you are
- * root (enter this password again to use it anyway).
- * --marekm
- */
- if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN")
- && !obscure(orig, pass, pw)) {
- (void) puts (_("\nWarning: weak password (enter it again to use it anyway)."));
- warned = true;
- continue;
+ /*
+ * If enabled, warn about weak passwords even if you are
+ * root (enter this password again to use it anyway).
+ * --marekm
+ */
+ if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN")
+ && !obscure(orig, pass, pw)) {
+ (void) puts (_("\nWarning: weak password (enter it again to use it anyway)."));
+ warned = true;
+ continue;
+ }
+ cp = agetpass (_("Re-enter new password: "));
+ if (NULL == cp) {
+ MEMZERO(orig);
+ MEMZERO(pass);
+ return -1;
+ }
+ if (strcmp (cp, pass) != 0) {
+ erase_pass (cp);
+ (void) fputs (_("They don't match; try again.\n"), stderr);
+ } else {
+ erase_pass (cp);
+ break;
+ }
}
- cp = agetpass (_("Re-enter new password: "));
- if (NULL == cp) {
- MEMZERO(orig);
+ MEMZERO(orig);
+
+ if (i == 0) {
MEMZERO(pass);
return -1;
}
- if (strcmp (cp, pass) != 0) {
- erase_pass (cp);
- (void) fputs (_("They don't match; try again.\n"), stderr);
- } else {
- erase_pass (cp);
- break;
- }
}
- MEMZERO(orig);
- if (i == 0) {
- MEMZERO(pass);
- return -1;
- }
/*
* Encrypt the password, then wipe the cleartext password.
* -u unlock the password of the named account (*)
* -w # set sp_warn to # days (*)
* -x # set sp_max to # days (*)
+ * -s read password from stdin (*)
*
* (*) requires root permission to execute.
*
{"unlock", no_argument, NULL, 'u'},
{"warndays", required_argument, NULL, 'w'},
{"maxdays", required_argument, NULL, 'x'},
+ {"stdin", no_argument, NULL, 's'},
{NULL, 0, NULL, '\0'}
};
- while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:P:Suw:x:",
+ while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:P:Suw:x:s",
long_options, NULL)) != -1) {
switch (c) {
case 'a':
xflg = true;
anyflag = true;
break;
+ case 's':
+ if (!amroot) {
+ (void) fprintf (stderr,
+ _("%s: only root can use --stdin/-s option\n"),
+ Prog);
+ usage (E_BAD_ARG);
+ }
+ sflg = true;
+ break;
default:
usage (E_BAD_ARG);
}
* Don't set the real UID for PAM...
*/
if (!anyflag && use_pam) {
- do_pam_passwd (name, qflg, kflg);
+ if (sflg) {
+ cp = agetpass_stdin ();
+ if (cp == NULL) {
+ exit (E_FAILURE);
+ }
+ do_pam_passwd_non_interactive ("passwd", name, cp);
+ erase_pass (cp);
+ } else {
+ do_pam_passwd (name, qflg, kflg);
+ }
exit (E_SUCCESS);
}
#endif /* USE_PAM */
return E_SUCCESS;
}
-