chpasswd.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * chpasswd.c
  4. *
  5. * Written for SLIND (from passwd.c) by Alexander Shishkin <virtuoso@slind.org>
  6. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  7. */
  8. #include "libbb.h"
  9. #if ENABLE_LONG_OPTS
  10. static const char chpasswd_longopts[] ALIGN1 =
  11. "encrypted\0" No_argument "e"
  12. "md5\0" No_argument "m"
  13. ;
  14. #endif
  15. #define OPT_ENC 1
  16. #define OPT_MD5 2
  17. int chpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  18. int chpasswd_main(int argc UNUSED_PARAM, char **argv)
  19. {
  20. char *name, *pass;
  21. char salt[sizeof("$N$XXXXXXXX")];
  22. int opt, rc;
  23. int rnd = rnd; /* we *want* it to be non-initialized! */
  24. if (getuid())
  25. bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
  26. opt_complementary = "m--e:e--m";
  27. IF_LONG_OPTS(applet_long_options = chpasswd_longopts;)
  28. opt = getopt32(argv, "em");
  29. while ((name = xmalloc_fgetline(stdin)) != NULL) {
  30. pass = strchr(name, ':');
  31. if (!pass)
  32. bb_error_msg_and_die("missing new password");
  33. *pass++ = '\0';
  34. xuname2uid(name); /* dies if there is no such user */
  35. if (!(opt & OPT_ENC)) {
  36. rnd = crypt_make_salt(salt, 1, rnd);
  37. if (opt & OPT_MD5) {
  38. strcpy(salt, "$1$");
  39. rnd = crypt_make_salt(salt + 3, 4, rnd);
  40. }
  41. pass = pw_encrypt(pass, salt, 0);
  42. }
  43. /* This is rather complex: if user is not found in /etc/shadow,
  44. * we try to find & change his passwd in /etc/passwd */
  45. #if ENABLE_FEATURE_SHADOWPASSWDS
  46. rc = update_passwd(bb_path_shadow_file, name, pass, NULL);
  47. if (rc == 0) /* no lines updated, no errors detected */
  48. #endif
  49. rc = update_passwd(bb_path_passwd_file, name, pass, NULL);
  50. /* LOGMODE_BOTH logs to syslog also */
  51. logmode = LOGMODE_BOTH;
  52. if (rc < 0)
  53. bb_error_msg_and_die("an error occurred updating password for %s", name);
  54. if (rc)
  55. bb_info_msg("Password for '%s' changed", name);
  56. logmode = LOGMODE_STDIO;
  57. free(name);
  58. if (!(opt & OPT_ENC))
  59. free(pass);
  60. }
  61. return EXIT_SUCCESS;
  62. }