Пример #1
0
int
main(int argc, char **argv)
{
	char hostname[MAXHOSTNAMELEN];
	struct passwd *pwd = NULL;
	int o, pam_err;
	uid_t uid;

	while ((o = getopt(argc, argv, "d:h:loy")) != -1)
		switch (o) {
		case 'd':
			yp_domain = optarg;
			break;
		case 'h':
			yp_host = optarg;
			break;
		case 'l':
		case 'o':
		case 'y':
			/* compatibility */
			break;
		default:
			usage();
		}

	argc -= optind;
	argv += optind;

	uid = getuid();

	switch (argc) {
	case 0:
		if ((pwd = getpwuid(uid)) == NULL)
			errx(1, "who are you?");
		break;
	case 1:
		if ((pwd = getpwnam(*argv)) == NULL)
			errx(1, "%s: no such user", *argv);
		break;
	default:
		usage();
	}

	if (uid != 0 && uid != pwd->pw_uid)
		errx(1, "permission denied");

	/* check where the user's from */
	switch (pwd->pw_fields & _PWF_SOURCE) {
	case _PWF_FILES:
		fprintf(stderr, "Changing local password for %s\n",
		    pwd->pw_name);
		break;
	case _PWF_NIS:
		fprintf(stderr, "Changing NIS password for %s\n",
		    pwd->pw_name);
		break;
	default:
		fprintf(stderr, "Changing password for %s\n",
		    pwd->pw_name);
	}

#define pam_check(func) do { \
	if (pam_err != PAM_SUCCESS) { \
		if (pam_err == PAM_AUTH_ERR || pam_err == PAM_PERM_DENIED || \
		    pam_err == PAM_AUTHTOK_RECOVERY_ERR) \
			warnx("sorry"); \
		else \
			warnx("%s(): %s", func, pam_strerror(pamh, pam_err)); \
		goto end; \
	} \
} while (0)

	/* initialize PAM */
	pam_err = pam_start("passwd", pwd->pw_name, &pamc, &pamh);
	pam_check("pam_start");

	pam_err = pam_set_item(pamh, PAM_TTY, ttyname(STDERR_FILENO));
	pam_check("pam_set_item");
	gethostname(hostname, sizeof hostname);
	pam_err = pam_set_item(pamh, PAM_RHOST, hostname);
	pam_check("pam_set_item");
	pam_err = pam_set_item(pamh, PAM_RUSER, getlogin());
	pam_check("pam_set_item");

	/* set YP domain and host */
	pam_err = pam_set_data(pamh, "yp_domain", yp_domain, NULL);
	pam_check("pam_set_data");
	pam_err = pam_set_data(pamh, "yp_server", yp_host, NULL);
	pam_check("pam_set_data");

	/* set new password */
	pam_err = pam_chauthtok(pamh, 0);
	pam_check("pam_chauthtok");

 end:
	pam_end(pamh, pam_err);
	exit(pam_err == PAM_SUCCESS ? 0 : 1);
}
Пример #2
0
void
pwpam_process(const char *username, int argc, char **argv)
{
	int ch, pam_err;
	char hostname[MAXHOSTNAMELEN + 1];

	/* details about the invoking user for logging */
	const uid_t i_uid = getuid();
	const struct passwd *const i_pwd = getpwuid(i_uid);
	const char *const i_username = (i_pwd && i_pwd->pw_name)
		? i_pwd->pw_name : "(null)";

	while ((ch = getopt(argc, argv, "")) != -1) {
		switch (ch) {
		default:
			usage();
			/* NOTREACHED */
		}
	}

	argc -= optind;
	argv += optind;

	switch (argc) {
	case 0:
		/* username already provided */
		break;
	case 1:
		username = argv[0];
		break;
	default:
		usage();
		/* NOTREACHED */
	}

	(void)printf("Changing password for %s.\n", username);

	/* initialize PAM -- always use the program name "passwd" */
	pam_err = pam_start("passwd", username, &pamc, &pamh);
	if (pam_err != PAM_SUCCESS)
		errx(1, "unable to start PAM session: %s",
		    pam_strerror(NULL, pam_err));

	pam_err = pam_set_item(pamh, PAM_TTY, ttyname(STDERR_FILENO));
	pam_check("unable to set TTY");

	(void)gethostname(hostname, sizeof hostname);
	pam_err = pam_set_item(pamh, PAM_RHOST, hostname);
	pam_check("unable to set RHOST");

	pam_err = pam_set_item(pamh, PAM_RUSER, getlogin());
	pam_check("unable to set RUSER");

	/* set new password */
	pam_err = pam_chauthtok(pamh, 0);
	if (pam_err != PAM_SUCCESS) {
		if (pam_err == PAM_PERM_DENIED) {
			syslog(LOG_AUTH | LOG_NOTICE,
			       "user %s (UID %lu) failed to change the "
			       "PAM authentication token of user %s: %s",
			       i_username, (unsigned long)i_uid, username,
			       pam_strerror(pamh, pam_err));
		}
		printf("Unable to change auth token: %s\n",
		    pam_strerror(pamh, pam_err));
	} else {
		syslog(LOG_AUTH | LOG_INFO,
		       "user %s (UID %lu) successfully changed the "
		       "PAM authentication token of user %s",
		       i_username, (unsigned long)i_uid, username);
	}

 end:
	pam_end(pamh, pam_err);
	if (pam_err == PAM_SUCCESS)
		return;
	exit(1);
}