📄 passwd.c
字号:
return E_SUCCESS; } if (stdin_flag && uid != 0) { fprintf (stderr, _("%s: Permission denied.\n"), program); sec_log (program, MSG_STDIN_FOR_NONROOT_DENIED, uid); return E_NOPERM; } if (S_flag && (admin_only || k_flag)) { print_error (program); return E_USAGE; } else { /* Determine our own user name for PAM authentication. */ while (getpwuid_r (uid, &resultbuf, buffer, buflen, &pw) != 0 && errno == ERANGE) { errno = 0; buflen += 256; buffer = alloca (buflen); } if (!pw) { sec_log (program, MSG_NO_ACCOUNT_FOUND, uid); fprintf (stderr, _("%s: Cannot determine your user name.\n"), program); return E_NOPERM; } caller_name = strdupa (pw->pw_name); /* We change the passwd information for another user, get that data, too. */ if (argc == 1) { while (getpwnam_r (argv[0], &resultbuf, buffer, buflen, &pw) != 0 && errno == ERANGE) { errno = 0; buflen += 256; buffer = alloca (buflen); } if (!pw) { fprintf (stderr, _("%s: Unknown user `%s'.\n"), program, argv[0]); return E_NOPERM; } } pw_data = do_getpwnam (pw->pw_name, use_service); if (pw_data == NULL || pw_data->service == S_NONE) { sec_log (program, MSG_UNKNOWN_USER, pw->pw_name, uid); if (use_service) fprintf (stderr, _("%s: User `%s' is not known to service `%s'\n"), program, pw->pw_name, use_service); else if (admin_only) /* Only print error, if we need the pw_data informations later. Else ignore it and let PAM do it. */ fprintf (stderr, _("%s: Unknown user `%s'.\n"), program, pw->pw_name); return E_NOPERM; } }#ifdef WITH_SELINUX if (is_selinux_enabled () > 0) { if ((uid == 0) && (selinux_check_access (pw->pw_name, PASSWD__PASSWD) != 0)) { security_context_t user_context; if (getprevcon (&user_context) < 0) user_context = (security_context_t) strdup (_("Unknown user context")); fprintf (stderr, _("%s: %s is not authorized to change the password of %s\n"), program, user_context, pw->pw_name); if (security_getenforce() > 0) { syslog (LOG_ALERT, "%s is not authorized to change the password of %s", user_context, pw->pw_name); freecon (user_context); exit (E_NOPERM); } else { fprintf (stderr, _("SELinux is in permissive mode, continuing\n")); freecon (user_context); } } }#endif /* Check if normal users are allowed to change the data. For NIS+ and LDAP, we let the service decide if the user is allowed. */ if (uid != 0 && pw_data->service != S_NISPLUS && pw_data->service != S_LDAP) { if (admin_only) { sec_log (program, MSG_PASSWORD_CHANGE_DENIED, pw_data->pw.pw_name, pw_data->pw.pw_uid, uid); fprintf(stderr, _("%s: Permission denied\n"), program); if (pw_data) free_user_t (pw_data); return E_NOPERM; } if (pw->pw_uid != uid) { sec_log (program, MSG_PASSWORD_CHANGE_DENIED, pw_data->pw.pw_name, pw_data->pw.pw_uid, uid); fprintf (stderr, _("You cannot change the shadow data for `%s'.\n"), pw->pw_name); syslog (LOG_WARNING, "%d cannot change shadow data for `%s'", uid, pw->pw_name); if (pw_data) free_user_t (pw_data); return E_NOPERM; } } if (S_flag) { sec_log (program, MSG_DISPLAY_PASSWORD_STATUS, pw_data->pw.pw_name, pw_data->pw.pw_uid, uid); display_pw (pw); if (pw_data) free_user_t (pw_data); return E_SUCCESS; } /* We only change the password, let PAM do it. */ if (!admin_only) { pam_handle_t *pamh = NULL; int flags = 0, ret; if (P_flag) { fprintf (stderr, _("%s: -P flag not supported in this mode!\n"), program); return E_USAGE; } if (stdin_flag) { char *ptr; char password[160]; /* 127 is the longest with current crypt */ int i; i = read (STDIN_FILENO, password, sizeof (password) - 1); if (i < 0) { fprintf (stderr, _("%s: error reading from stdin!\n"), program); return E_FAILURE; } password[i] = '\0'; /* Remove trailing \n. */ ptr = strchr (password, '\n'); if (ptr) *ptr = 0; conv.conv = stdin_conv; conv.appdata_ptr = strdup (password); } if (!silent) printf (_("Changing password for %s.\n"), pw->pw_name); if (silent) flags |= PAM_SILENT; if (k_flag) flags |= PAM_CHANGE_EXPIRED_AUTHTOK; ret = pam_start ("passwd", pw->pw_name, &conv, &pamh); if (ret != PAM_SUCCESS) { fprintf (stderr, _("%s: PAM Failure, aborting: %s\n"), program, pam_strerror (pamh, ret)); syslog (LOG_ERR, "Couldn't initialize PAM: %s", pam_strerror (pamh, ret)); if (pw_data) free_user_t (pw_data); return E_PAM_ERROR; } ret = pam_chauthtok (pamh, flags); if (ret != PAM_SUCCESS) { syslog (LOG_ERR, "User %s: %s", caller_name, pam_strerror (pamh, ret)); sec_log (program, MSG_PASSWORD_CHANGE_FAILED, ret, pw_data->pw.pw_name, pw_data->pw.pw_uid, uid); sleep (getlogindefs_num ("FAIL_DELAY", 1)); fprintf (stderr, "%s: %s\n", program, pam_strerror (pamh, ret)); if (pw_data) free_user_t (pw_data); return E_PAM_ERROR; } pam_end (pamh, PAM_SUCCESS); sec_log (program, MSG_PASSWORD_CHANGED, pw_data->pw.pw_name, pw_data->pw.pw_uid, uid); free_user_t (pw_data); return E_SUCCESS; } if (binddn) { char prompt[130+strlen (binddn)], *cp; pw_data->binddn = strdup (binddn); snprintf (prompt, sizeof (prompt), _("Enter LDAP Password:")); cp = getpass (prompt); pw_data->oldclearpwd = strdup (cp); } if (d_flag) pw_data->newpassword = strdup (""); if (u_flag) { if (pw_data->use_shadow) { /* If the password is only "!", don't unlock it. */ if (pw_data->sp.sp_pwdp[0] == '!' && strlen (pw_data->sp.sp_pwdp) > 1) pw_data->newpassword = strdup (&pw_data->sp.sp_pwdp[1]); else { fprintf (stderr, _("Cannot unlock the password for `%s'!\n"), pw_data->pw.pw_name); free_user_t (pw_data); return E_FAILURE; } } else { /* If the password is only "!", don't unlock it. */ if (pw_data->pw.pw_passwd[0] == '!' && strlen (pw_data->pw.pw_passwd) > 1) pw_data->newpassword = strdup (&pw_data->pw.pw_passwd[1]); else { fprintf (stderr, _("Cannot unlock the password for `%s'!\n"), pw_data->pw.pw_name); free_user_t (pw_data); return E_FAILURE; } } } if (l_flag) { if (pw_data->use_shadow) { if (pw_data->sp.sp_pwdp[0] != '!') { pw_data->newpassword = malloc (strlen (pw_data->sp.sp_pwdp) + 2); if (pw_data->newpassword == NULL) return E_FAILURE; strcpy (&pw_data->newpassword[1], pw_data->sp.sp_pwdp); pw_data->newpassword[0] = '!'; } else { fprintf (stderr, _("Password for `%s' is already locked!\n"), pw_data->pw.pw_name); free_user_t (pw_data); return E_FAILURE; } } else { if (pw_data->pw.pw_passwd[0] != '!') { pw_data->newpassword = malloc (strlen (pw_data->pw.pw_passwd) + 2); if (pw_data->newpassword == NULL) return E_FAILURE; strcpy (&pw_data->newpassword[1], pw_data->pw.pw_passwd); pw_data->newpassword[0] = '!'; } else { fprintf (stderr, _("Password for `%s' is already locked!\n"), pw_data->pw.pw_name); free_user_t (pw_data); return E_FAILURE; } } } if (x_flag) pw_data->spn.sp_max = (age_max * DAY) / SCALE; if (n_flag) pw_data->spn.sp_min = (age_min * DAY) / SCALE; if (w_flag) pw_data->spn.sp_warn = (warn * DAY) / SCALE; if (i_flag) pw_data->spn.sp_inact = (inact * DAY) / SCALE; if (e_flag) pw_data->spn.sp_lstchg = 0; if (x_flag || n_flag || w_flag || i_flag || e_flag || e_flag) pw_data->sp_changed = TRUE; if (write_user_data (pw_data, 0) != 0) { if (pw_data->sp_changed) fprintf (stderr, _("Error while changing password expiry information.\n")); else fprintf (stderr, _("Error while changing password.\n")); free_user_t (pw_data); return E_FAILURE; } else {#ifdef HAVE_NSCD_FLUSH_CACHE nscd_flush_cache ("passwd");#endif if (!silent) { if (pw_data->sp_changed) printf (_("Password expiry information changed.\n")); else printf (_("Password changed.\n")); } } sec_log (program, MSG_PASSWORD_CHANGED, pw_data->pw.pw_name, pw_data->pw.pw_uid, uid); free_user_t (pw_data); return E_SUCCESS;}intmain (int argc, char **argv){ int retval; char *prog; setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); prog = basename (argv[0]); open_sec_log (prog); /* Before going any further, raise the ulimit and ignore signals. */ init_environment (); /* easy way to get ride of the first argument. */ if (argc > 1 && argv[1][0] == '-' && strchr ("gfs", argv[1][1])) { char buf[200]; setuid (getuid ()); switch (argv[1][1]) { case 'g': argv[1] = GPASSWD_PROGRAM; /* XXX warning: const */ break; case 'f': argv[1] = CHFN_PROGRAM; /* XXX warning: const */ break; case 's': argv[1] = CHSH_PROGRAM; /* XXX warning: const */ break; default: /* If this happens we have a real problem. */ abort (); } snprintf (buf, sizeof buf, _("passwd: Cannot execute %s"), argv[1]); execvp(argv[1], &argv[1]); perror(buf); syslog (LOG_ERR, "Cannot execute %s", argv[1]); closelog (); return E_FAILURE; } retval = passwd_main (prog, argc, argv); closelog (); return retval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -