예제 #1
0
파일: pwio.c 프로젝트: DavidChenLiang/study
/*@observer@*/ /*@null@*/const struct passwd *pw_locate_uid (uid_t uid)
{
	const struct passwd *pwd;

	pw_rewind ();
	while (   ((pwd = pw_next ()) != NULL)
	       && (pwd->pw_uid != uid)) {
	}

	return pwd;
}
예제 #2
0
파일: pwunconv.c 프로젝트: Romutk/SPIVT1
int main (int argc, char **argv)
{
	const struct passwd *pw;
	struct passwd pwent;
	const struct spwd *spwd;

	if (1 != argc) {
		(void) fputs (_("Usage: pwunconv\n"), stderr);
	}
	Prog = Basename (argv[0]);

	(void) setlocale (LC_ALL, "");
	(void) bindtextdomain (PACKAGE, LOCALEDIR);
	(void) textdomain (PACKAGE);

	OPENLOG ("pwunconv");

#ifdef WITH_TCB
	if (getdef_bool("USE_TCB")) {
		fprintf(stderr, _("%s: can't work with tcb enabled\n"), Prog);
		exit(1);
	}
#endif				/* WITH_TCB */

	if (!spw_file_present ()) {
		/* shadow not installed, do nothing */
		exit (0);
	}

	if (pw_lock () == 0) {
		fprintf (stderr,
		         _("%s: cannot lock %s; try again later.\n"),
		         Prog, pw_dbname ());
		fail_exit (5);
	}
	pw_locked = true;
	if (pw_open (O_RDWR) == 0) {
		fprintf (stderr,
		         _("%s: cannot open %s\n"),
		         Prog, pw_dbname ());
		fail_exit (1);
	}

	if (spw_lock () == 0) {
		fprintf (stderr,
		         _("%s: cannot lock %s; try again later.\n"),
		         Prog, spw_dbname ());
		fail_exit (5);
	}
	spw_locked = true;
	if (spw_open (O_RDWR) == 0) {
		fprintf (stderr,
		         _("%s: cannot open %s\n"),
		         Prog, spw_dbname ());
		fail_exit (1);
	}

	pw_rewind ();
	while ((pw = pw_next ()) != NULL) {
		spwd = spw_locate (pw->pw_name);
		if (NULL == spwd) {
			continue;
		}

		pwent = *pw;

		/*
		 * Update password if non-shadow is "x".
		 */
		if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
			pwent.pw_passwd = spwd->sp_pwdp;
		}

		/*
		 * Password aging works differently in the two different
		 * systems. With shadow password files you apparently must
		 * have some aging information. The maxweeks or minweeks
		 * may not map exactly. In pwconv we set max == 10000,
		 * which is about 30 years. Here we have to undo that
		 * kludge. So, if maxdays == 10000, no aging information is
		 * put into the new file. Otherwise, the days are converted
		 * to weeks and so on.
		 */
		if (pw_update (&pwent) == 0) {
			fprintf (stderr,
			         _("%s: failed to prepare the new %s entry '%s'\n"),
			         Prog, pw_dbname (), pwent.pw_name);
			fail_exit (3);
		}
	}

	if (spw_close () == 0) {
		fprintf (stderr,
		         _("%s: failure while writing changes to %s\n"),
		         Prog, spw_dbname ());
		SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ()));
		fail_exit (3);
	}

	if (pw_close () == 0) {
		fprintf (stderr,
		         _("%s: failure while writing changes to %s\n"),
		         Prog, pw_dbname ());
		SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ()));
		fail_exit (3);
	}

	if (unlink (SHADOW) != 0) {
		fprintf (stderr,
			 _("%s: cannot delete %s\n"), Prog, SHADOW);
		SYSLOG ((LOG_ERR, "cannot delete %s", SHADOW));
		fail_exit (3);
	}

	if (spw_unlock () == 0) {
		fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
		SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
		/* continue */
	}
	if (pw_unlock () == 0) {
		fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ());
		SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
		/* continue */
	}

	nscd_flush_cache ("passwd");

	return 0;
}
예제 #3
0
int main (int argc, char **argv)
{
	const struct passwd *pw;
	struct passwd pwent;
	const struct spwd *spwd;

#ifdef	ATT_AGE
	char newage[5];
#endif
	char *Prog = argv[0];

	setlocale (LC_ALL, "");
	bindtextdomain (PACKAGE, LOCALEDIR);
	textdomain (PACKAGE);

	if (!spw_file_present ())
		/* shadow not installed, do nothing */
		exit (0);

	if (!pw_lock ()) {
		fprintf (stderr, _("%s: can't lock passwd file\n"), Prog);
		fail_exit (5);
	}
	passwd_locked++;
	if (!pw_open (O_RDWR)) {
		fprintf (stderr, _("%s: can't open passwd file\n"), Prog);
		fail_exit (1);
	}

	if (!spw_lock ()) {
		fprintf (stderr, _("%s: can't open shadow file\n"), Prog);
		fail_exit (5);
	}
	shadow_locked++;
	if (!spw_open (O_RDWR)) {
		fprintf (stderr, _("%s: can't open shadow file\n"), Prog);
		fail_exit (1);
	}

	pw_rewind ();
	while ((pw = pw_next ())) {
		if (!(spwd = spw_locate (pw->pw_name)))
			continue;

		pwent = *pw;

		/*
		 * Update password if non-shadow is "x".
		 */
		if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0)
			pwent.pw_passwd = spwd->sp_pwdp;

		/*
		 * Password aging works differently in the two different
		 * systems. With shadow password files you apparently must
		 * have some aging information. The maxweeks or minweeks
		 * may not map exactly. In pwconv we set max == 10000,
		 * which is about 30 years. Here we have to undo that
		 * kludge. So, if maxdays == 10000, no aging information is
		 * put into the new file. Otherwise, the days are converted
		 * to weeks and so on.
		 */

#ifdef	ATT_AGE
		if (spwd->sp_max > (63 * WEEK / SCALE)
		    && spwd->sp_max < 10000)
			spwd->sp_max = (63 * WEEK / SCALE);	/* 10000 is infinity */

		if (spwd->sp_min >= 0 && spwd->sp_min <= 63 * 7 &&
		    spwd->sp_max >= 0 && spwd->sp_max <= 63 * 7) {
			if (spwd->sp_lstchg == -1)
				spwd->sp_lstchg = 0;

			spwd->sp_max /= WEEK / SCALE;	/* turn it into weeks */
			spwd->sp_min /= WEEK / SCALE;
			spwd->sp_lstchg /= WEEK / SCALE;

			strncpy (newage,
				 l64a (spwd->sp_lstchg * (64L * 64L) +
				       spwd->sp_min * (64L) +
				       spwd->sp_max), 5);
			pwent.pw_age = newage;
		} else
			pwent.pw_age = "";
#endif				/* ATT_AGE */
		if (!pw_update (&pwent)) {
			fprintf (stderr,
				 _("%s: can't update entry for user %s\n"),
				 Prog, pwent.pw_name);
			fail_exit (3);
		}
	}

	if (!spw_close ()) {
		fprintf (stderr,
			 _("%s: can't update shadow password file\n"),
			 Prog);
		fail_exit (3);
	}

	if (!pw_close ()) {
		fprintf (stderr, _("%s: can't update password file\n"),
			 Prog);
		fail_exit (3);
	}

	if (unlink (SHADOW) != 0) {
		fprintf (stderr,
			 _("%s: can't delete shadow password file\n"),
			 Prog);
		fail_exit (3);
	}

	spw_unlock ();
	pw_unlock ();
	return 0;
}
예제 #4
0
int main (int argc, char **argv)
{
	const struct passwd *pw;
	struct passwd pwent;
	const struct spwd *sp;
	struct spwd spent;

	Prog = Basename (argv[0]);

	(void) setlocale (LC_ALL, "");
	(void) bindtextdomain (PACKAGE, LOCALEDIR);
	(void) textdomain (PACKAGE);

	process_root_flag ("-R", argc, argv);

	OPENLOG ("pwconv");

	process_flags (argc, argv);

#ifdef WITH_TCB
	if (getdef_bool("USE_TCB")) {
		fprintf (stderr, _("%s: can't work with tcb enabled\n"), Prog);
		exit (E_FAILURE);
	}
#endif				/* WITH_TCB */

	if (pw_lock () == 0) {
		fprintf (stderr,
		         _("%s: cannot lock %s; try again later.\n"),
		         Prog, pw_dbname ());
		fail_exit (E_PWDBUSY);
	}
	pw_locked = true;
	if (pw_open (O_RDWR) == 0) {
		fprintf (stderr,
		         _("%s: cannot open %s\n"), Prog, pw_dbname ());
		fail_exit (E_MISSING);
	}

	if (spw_lock () == 0) {
		fprintf (stderr,
		         _("%s: cannot lock %s; try again later.\n"),
		         Prog, spw_dbname ());
		fail_exit (E_PWDBUSY);
	}
	spw_locked = true;
	if (spw_open (O_CREAT | O_RDWR) == 0) {
		fprintf (stderr,
		         _("%s: cannot open %s\n"), Prog, spw_dbname ());
		fail_exit (E_FAILURE);
	}

	/*
	 * Remove /etc/shadow entries for users not in /etc/passwd.
	 */
	(void) spw_rewind ();
	while ((sp = spw_next ()) != NULL) {
		if (pw_locate (sp->sp_namp) != NULL) {
			continue;
		}

		if (spw_remove (sp->sp_namp) == 0) {
			/*
			 * This shouldn't happen (the entry exists) but...
			 */
			fprintf (stderr,
			         _("%s: cannot remove entry '%s' from %s\n"),
			         Prog, sp->sp_namp, spw_dbname ());
			fail_exit (E_FAILURE);
		}
	}

	/*
	 * Update shadow entries which don't have "x" as pw_passwd. Add any
	 * missing shadow entries.
	 */
	(void) pw_rewind ();
	while ((pw = pw_next ()) != NULL) {
		sp = spw_locate (pw->pw_name);
		if (NULL != sp) {
			/* do we need to update this entry? */
			if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
				continue;
			}
			/* update existing shadow entry */
			spent = *sp;
		} else {
			/* add new shadow entry */
			memset (&spent, 0, sizeof spent);
			spent.sp_namp   = pw->pw_name;
			spent.sp_min    = getdef_num ("PASS_MIN_DAYS", -1);
			spent.sp_max    = getdef_num ("PASS_MAX_DAYS", -1);
			spent.sp_warn   = getdef_num ("PASS_WARN_AGE", -1);
			spent.sp_inact  = -1;
			spent.sp_expire = -1;
			spent.sp_flag   = SHADOW_SP_FLAG_UNSET;
		}
		spent.sp_pwdp = pw->pw_passwd;
		spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
		if (0 == spent.sp_lstchg) {
			/* Better disable aging than requiring a password
			 * change */
			spent.sp_lstchg = -1;
		}
		if (spw_update (&spent) == 0) {
			fprintf (stderr,
			         _("%s: failed to prepare the new %s entry '%s'\n"),
			         Prog, spw_dbname (), spent.sp_namp);
			fail_exit (E_FAILURE);
		}

		/* remove password from /etc/passwd */
		pwent = *pw;
		pwent.pw_passwd = SHADOW_PASSWD_STRING;	/* XXX warning: const */
		if (pw_update (&pwent) == 0) {
			fprintf (stderr,
			         _("%s: failed to prepare the new %s entry '%s'\n"),
			         Prog, pw_dbname (), pwent.pw_name);
			fail_exit (E_FAILURE);
		}
	}

	if (spw_close () == 0) {
		fprintf (stderr,
		         _("%s: failure while writing changes to %s\n"),
		         Prog, spw_dbname ());
		SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ()));
		fail_exit (E_FAILURE);
	}
	if (pw_close () == 0) {
		fprintf (stderr,
		         _("%s: failure while writing changes to %s\n"),
		         Prog, pw_dbname ());
		SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ()));
		fail_exit (E_FAILURE);
	}

	/* /etc/passwd- (backup file) */
	if (chmod (PASSWD_FILE "-", 0600) != 0) {
		fprintf (stderr,
		         _("%s: failed to change the mode of %s to 0600\n"),
		         Prog, PASSWD_FILE "-");
		SYSLOG ((LOG_ERR, "failed to change the mode of %s to 0600", PASSWD_FILE "-"));
		/* continue */
	}

	if (pw_unlock () == 0) {
		fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ());
		SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
		/* continue */
	}

	if (spw_unlock () == 0) {
		fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
		SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
		/* continue */
	}

	nscd_flush_cache ("passwd");

	return E_SUCCESS;
}
예제 #5
0
static void
update_user(void)
{
#if defined(AUTH_METHODS) || defined(NDBM)
	struct	passwd	*pwd;
#endif
#ifdef AUTH_METHODS
#ifdef	SHADOWPWD
	struct	spwd	*spwd;

	if (is_shadow_pwd && (spwd = spw_locate (user_name)) &&
	    spwd->sp_pwdp[0] == '@') {
		if (pw_auth (spwd->sp_pwdp + 1, user_name, PW_DELETE, (char *) 0)) {
			SYSLOG((LOG_ERR,
				"failed deleting auth `%s' for user `%s'\n",
				spwd->sp_pwdp + 1, user_name));
			fprintf(stderr,
				_("%s: error deleting authentication\n"),
				Prog);
		} else {
			SYSLOG((LOG_INFO,
				"delete auth `%s' for user `%s'\n",
				spwd->sp_pwdp + 1, user_name));
		}
	}
#endif	/* SHADOWPWD */
	if ((pwd = pw_locate(user_name)) && pwd->pw_passwd[0] == '@') {
		if (pw_auth(pwd->pw_passwd + 1, user_name, PW_DELETE, (char *) 0)) {
			SYSLOG((LOG_ERR,
				"failed deleting auth `%s' for user `%s'\n",
				pwd->pw_passwd + 1, user_name));
			fprintf(stderr,
				_("%s: error deleting authentication\n"),
				Prog);
		} else {
			SYSLOG((LOG_INFO, "delete auth `%s' for user `%s'\n",
				pwd->pw_passwd + 1, user_name);
		}
	}
#endif  /* AUTH_METHODS */
	if (!pw_remove(user_name))
		fprintf(stderr, _("%s: error deleting password entry\n"), Prog);
#ifdef	SHADOWPWD
	if (is_shadow_pwd && ! spw_remove (user_name))
		fprintf(stderr, _("%s: error deleting shadow password entry\n"),
			Prog);
#endif
#ifdef	HAVE_TCFS
	if (tcfs_locate (user_name)) {
		if (!tcfs_remove (user_name)) {
			SYSLOG((LOG_ERR,
				"failed deleting TCFS entry for user `%s'\n",
				user_name));
			fprintf(stderr, _("%s: error deleting TCFS entry\n"),
				Prog);
		} else {
			SYSLOG((LOG_INFO,
				"delete TCFS entry for user `%s'\n",
				user_name));
		}
	}
#endif	/* HAVE_TCFS */
#ifdef NDBM
	if (pw_dbm_present()) {
		if ((pwd = getpwnam (user_name)) && ! pw_dbm_remove (pwd))
			fprintf(stderr,
				_("%s: error deleting password dbm entry\n"),
				Prog);
	}

	/*
	 * If the user's UID is a duplicate the duplicated entry needs
	 * to be updated so that a UID match can be found in the DBM
	 * files.
	 */

	for (pw_rewind (), pwd = pw_next ();pwd;pwd = pw_next ()) {
		if (pwd->pw_uid == user_id) {
			pw_dbm_update (pwd);
			break;
		}
	}
#ifdef SHADOWPWD
	if (is_shadow_pwd && sp_dbm_present() && !sp_dbm_remove(user_name))
		fprintf(stderr,
			_("%s: error deleting shadow passwd dbm entry\n"),
			Prog);

	endspent ();
#endif
	endpwent ();
#endif /* NDBM */
	SYSLOG((LOG_INFO, "delete user `%s'\n", user_name));
}