예제 #1
0
PAMH_ARG_DECL(int get_account_info,
	const char *name, struct passwd **pwd, struct spwd **spwdent)
{
	/* UNIX passwords area */
	*pwd = pam_modutil_getpwnam(pamh, name);	/* Get password file entry... */
	*spwdent = NULL;

	if (*pwd != NULL) {
		if (strcmp((*pwd)->pw_passwd, "*NP*") == 0)
		{ /* NIS+ */
#ifdef HELPER_COMPILE
			uid_t save_euid, save_uid;

			save_euid = geteuid();
			save_uid = getuid();
			if (save_uid == (*pwd)->pw_uid)
				setreuid(save_euid, save_uid);
			else  {
				setreuid(0, -1);
				if (setreuid(-1, (*pwd)->pw_uid) == -1) {
					setreuid(-1, 0);
					setreuid(0, -1);
					if(setreuid(-1, (*pwd)->pw_uid) == -1)
						return PAM_CRED_INSUFFICIENT;
				}
			}

			*spwdent = pam_modutil_getspnam(pamh, name);
			if (save_uid == (*pwd)->pw_uid)
				setreuid(save_uid, save_euid);
			else {
				setreuid(-1, 0);
				setreuid(save_uid, -1);
				setreuid(-1, save_euid);
			}

			if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL)
				return PAM_AUTHINFO_UNAVAIL;
#else
			/* we must run helper for NIS+ passwords */
			return PAM_UNIX_RUN_HELPER;
#endif
		} else if (is_pwd_shadowed(*pwd)) {
			/*
			 * ...and shadow password file entry for this user,
			 * if shadowing is enabled
			 */
#ifndef HELPER_COMPILE
			if (geteuid() || SELINUX_ENABLED)
				return PAM_UNIX_RUN_HELPER;
#endif
			*spwdent = pam_modutil_getspnam(pamh, name);
			if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL)
				return PAM_AUTHINFO_UNAVAIL;
		}
	} else {
		return PAM_USER_UNKNOWN;
	}
	return PAM_SUCCESS;
}
예제 #2
0
int
pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
{
  struct passwd *pwd;
  const char *newpass;
  const char *user;
    int retval, tries;
  options_t options;

  memset (&options, 0, sizeof (options));

  /* Set some default values, which could be overwritten later.  */
  options.remember = 10;
  options.tries = 1;

  /* Parse parameters for module */
  for ( ; argc-- > 0; argv++)
    parse_option (pamh, *argv, &options);

  if (options.debug)
    pam_syslog (pamh, LOG_DEBUG, "pam_sm_chauthtok entered");


  if (options.remember == 0)
    return PAM_IGNORE;

  retval = pam_get_user (pamh, &user, NULL);
  if (retval != PAM_SUCCESS)
    return retval;

  if (user == NULL || strlen (user) == 0)
    {
      if (options.debug)
	pam_syslog (pamh, LOG_DEBUG,
		    "User is not known to system");

      return PAM_USER_UNKNOWN;
    }

  if (flags & PAM_PRELIM_CHECK)
    {
      if (options.debug)
	pam_syslog (pamh, LOG_DEBUG,
		    "pam_sm_chauthtok(PAM_PRELIM_CHECK)");

      return PAM_SUCCESS;
    }

  pwd = pam_modutil_getpwnam (pamh, user);
  if (pwd == NULL)
    return PAM_USER_UNKNOWN;

  if ((strcmp(pwd->pw_passwd, "x") == 0)  ||
      ((pwd->pw_passwd[0] == '#') &&
       (pwd->pw_passwd[1] == '#') &&
       (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)))
    {
      struct spwd *spw = pam_modutil_getspnam (pamh, user);
      if (spw == NULL)
	return PAM_USER_UNKNOWN;

      retval = save_old_pass (pamh, user, pwd->pw_uid, spw->sp_pwdp,
			      options.remember, options.debug);
      if (retval != PAM_SUCCESS)
	return retval;
    }
  else
    {
      retval = save_old_pass (pamh, user, pwd->pw_uid, pwd->pw_passwd,
			      options.remember, options.debug);
      if (retval != PAM_SUCCESS)
	return retval;
    }

  newpass = NULL;
  tries = 0;
  while ((newpass == NULL) && (tries < options.tries))
    {
      retval = pam_get_authtok (pamh, PAM_AUTHTOK, &newpass, NULL);
      if (retval != PAM_SUCCESS && retval != PAM_TRY_AGAIN)
	{
	  if (retval == PAM_CONV_AGAIN)
	    retval = PAM_INCOMPLETE;
	  return retval;
	}
      tries++;

      if (options.debug)
	{
	  if (newpass)
	    pam_syslog (pamh, LOG_DEBUG, "got new auth token");
	  else
	    pam_syslog (pamh, LOG_DEBUG, "got no auth token");
	}

      if (newpass == NULL || retval == PAM_TRY_AGAIN)
	continue;

      if (options.debug)
	pam_syslog (pamh, LOG_DEBUG, "check against old password file");

      if (check_old_pass (pamh, user, newpass,
			  options.debug) != PAM_SUCCESS)
	{
	  if (getuid() || options.enforce_for_root ||
	      (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
	    {
	      pam_error (pamh,
		         _("Password has been already used. Choose another."));
	      newpass = NULL;
	      /* Remove password item, else following module will use it */
	      pam_set_item (pamh, PAM_AUTHTOK, (void *) NULL);
	    }
	  else
	    pam_info (pamh,
		       _("Password has been already used."));
	}
    }

  if (newpass == NULL && tries >= options.tries)
    {
      if (options.debug)
	pam_syslog (pamh, LOG_DEBUG, "Aborted, too many tries");
      return PAM_MAXTRIES;
    }

  return PAM_SUCCESS;
}