Exemple #1
0
void pw_entry (const char *name, struct passwd *pwent)
{
	struct passwd *passwd;

	struct spwd *spwd;

	if (!(passwd = getpwnam (name))) {
		pwent->pw_name = (char *) 0;
		return;
	} else {
		pwent->pw_name = xstrdup (passwd->pw_name);
		pwent->pw_uid = passwd->pw_uid;
		pwent->pw_gid = passwd->pw_gid;
		pwent->pw_gecos = xstrdup (passwd->pw_gecos);
		pwent->pw_dir = xstrdup (passwd->pw_dir);
		pwent->pw_shell = xstrdup (passwd->pw_shell);
#if !defined(AUTOSHADOW)
		setspent ();
		if ((spwd = getspnam (name))) {
			pwent->pw_passwd = xstrdup (spwd->sp_pwdp);
			endspent ();
			return;
		}
		endspent ();
#endif
		pwent->pw_passwd = xstrdup (passwd->pw_passwd);
	}
}
Exemple #2
0
static const char *
getpw(void)
{
    const char *rval;
    struct passwd *pw;
    pw = getpwuid(getuid());

    if (pw == NULL)
        die("lock: cannot retrieve password entry\n"
            "(make sure to setcap CAP_DAC_READ_SEARCH+ep)\n");

    endpwent();

    if (pw->pw_passwd[0] != '\0')        /* there is a placeholder */
    {
        struct spwd *sp;
        sp = getspnam(pw->pw_name);

        if (sp == NULL)
            die("lock: cannot retrieve shadow entry\n"
                "(make sure to setcap CAP_DAC_READ_SEARCH+ep)\n");

        endspent();
        rval = sp->sp_pwdp;
    }
    else
        rval =  pw->pw_passwd;

    return rval;
}
Exemple #3
0
static int
do_classic_auth (const char *username, const char *password)
{
    int ret = 0;
    const char *encr_pwd = NULL;
    struct passwd *pw;
#ifdef HAVE_SHADOW
    struct spwd *spw;
#endif

    if ((pw = getpwnam (username)) == 0)
	return 0;

#ifdef HAVE_SHADOW
    setspent ();

    /* Password expiration is not checked! */
    if ((spw = getspnam (username)) == NULL)
	encr_pwd = "*";
    else
	encr_pwd = spw->sp_pwdp;

    endspent ();
#else
    encr_pwd = pw->pw_passwd;
#endif

    if (strcmp (crypt (password, encr_pwd), encr_pwd) == 0)
	ret = 1;

    endpwent ();
    return ret;
}
Exemple #4
0
static int
correct_password (const struct passwd *pw)
{
  char unencrypted[1024], *encrypted, *correct;
#ifdef HAVE_SHADOW_H
  /* Shadow passwd stuff for SVR3 and maybe other systems.  */
  struct spwd *sp = getspnam (pw->pw_name);

  endspent ();
  if (sp)
    correct = sp->sp_pwdp;
  else
#endif
    correct = pw->pw_passwd;

  if (getuid () == 0 || correct == 0 || correct[0] == '\0')
    return 1;

  fprintf (outf, PROTOCOL_ASK_PASS);
  memset (unencrypted, 0, sizeof (unencrypted));
  if (fgets (unencrypted, sizeof (unencrypted), inf) == NULL)
    {
      fprintf (outf, PROTOCOL_ERROR);
      exit (1);
    }

  if (strlen (unencrypted) && unencrypted[strlen (unencrypted) - 1] == 10)
      unencrypted[strlen (unencrypted) - 1] = 0;

  encrypted = crypt (unencrypted, correct);
  memset (unencrypted, 0, sizeof (unencrypted));
  return strcmp (encrypted, correct) == 0;
}
Exemple #5
0
int main(int argc, char *argv[]) {
   off_t who_am_i = getuid();
   struct spwd *sp, *sp2;
   char *user = "******";

   if (who_am_i != 0) {
      fprintf(stderr, "Only root can read shadow password database baby!\n");
      exit(EXIT_FAILURE);
   }

   if ((sp = getspnam("b3h3m0th")) == NULL) {
      fprintf(stderr, "Err. %s reading gestpnam()\n", strerror(errno));
      exit(EXIT_FAILURE);
   }
   printf("     user name: %s\n", sp->sp_namp);
   printf("encrypted pass: %s\n", sp->sp_pwdp);

   setspent();

   while ((sp2 = getspent()) != NULL) {
      if(strcmp(user, sp2->sp_namp) == 0) {
      	 printf("User %s presente nel sistema\n", user);
	 break;
      }
      printf("Searching...\n");
   }

   endspent();

   return(EXIT_SUCCESS);
}
Exemple #6
0
static const char *
get_password(char *username) { /* only run as root */
    const char *rval;
    struct passwd *pw;

    if(geteuid() != 0)
        die("sflock: cannot retrieve password entry (make sure to suid sflock)\n");
    pw = getpwuid(getuid());
    endpwent();
    rval =  pw->pw_passwd;

#if HAVE_SHADOW_H
    {
        struct spwd *sp;
        sp = getspnam(username);
        endspent();
        rval = sp->sp_pwdp;
    }
#endif

    /* drop privileges temporarily */
    if (setreuid(0, pw->pw_uid) == -1)
        die("sflock: cannot drop privileges\n");
    return rval;
}
Exemple #7
0
int Input::Correct() {
    char *unencrypted, *encrypted, *correct;
    struct passwd *pw;

    pw = getpwnam(NameBuffer);
    endpwent();
    if(pw == 0)
        return 0;

#ifdef HAVE_SHADOW
    struct spwd *sp = getspnam(pw->pw_name);    
    endspent();
    if(sp)
	correct = sp->sp_pwdp;
    else
#endif
	correct = pw->pw_passwd;

    if(correct == 0 || correct[0] == '\0')
        return 1;

    unencrypted = PasswdBuffer;
    encrypted = crypt(unencrypted, correct);
    memset(unencrypted, 0, strlen (unencrypted));
    return (strcmp(encrypted, correct) == 0);
}
Exemple #8
0
static const char *
get_password() { /* only run as root */
	const char *rval;
	struct passwd *pw;

	if(geteuid() != 0)
		die("slock: cannot retrieve password entry (make sure to suid slock)\n");
	pw = getpwuid(getuid());
	endpwent();
	rval =  pw->pw_passwd;

#if HAVE_SHADOW_H
	{
		struct spwd *sp;
		sp = getspnam(getenv("USER"));
		endspent();
		rval = sp->sp_pwdp;
	}
#endif

	/* drop privileges */
	if(setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0)
		die("slock: cannot drop privileges\n");
	return rval;
}
Exemple #9
0
uid_t SecurityManager::authenticate(char *userName, char *password) {
#ifdef __APPLE__
	// lckpwdf etc. are not supported by MacOS.
	return (uid_t)-1;
#else
	if ((userName == NULL) || (password == NULL))
		return (uid_t)-1;
	uid_t result = (uid_t)-1;
	lckpwdf();
	setpwent();
	setspent();
	struct passwd *passwdEntry = getpwnam(userName);
	struct spwd *shadowEntry = getspnam(userName);
	if ((shadowEntry != NULL) && (passwdEntry != NULL)) {
		char *plain = password;
		char *encrypted = shadowEntry->sp_pwdp;
		if (strcmp(crypt(plain, encrypted), encrypted) == 0)
			result = passwdEntry->pw_uid;
	}
	endpwent();
	endspent();
	ulckpwdf();
	return result;
#endif
} // end of authenticate(char*, char*)
Exemple #10
0
static const char *
getpw(void) { /* only run as root */
	const char *rval;
	struct passwd *pw;

	pw = getpwuid(getuid());
	if(!pw)
		die("slock: cannot retrieve password entry (make sure to suid or sgid slock)");
	endpwent();
	rval =  pw->pw_passwd;

#if HAVE_SHADOW_H
	if (strlen(rval) >= 1) { /* kludge, assumes pw placeholder entry has len >= 1 */
		struct spwd *sp;
		sp = getspnam(getenv("USER"));
		if(!sp)
			die("slock: cannot retrieve shadow entry (make sure to suid or sgid slock)\n");
		endspent();
		rval = sp->sp_pwdp;
	}
#endif

	/* drop privileges */
	if(setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0)
		die("slock: cannot drop privileges");
	return rval;
}
Exemple #11
0
/*
 * Read /etc/shadow.
 */
void
readshadow(void)
{
#ifdef	SHADOW_PWD
	struct login *lp;
	struct spwd *sp;
	size_t sz;

	setspent();
	while (sp = getspent()) {
		if ((lp = findlogin(sp->sp_namp)) == NULL)
			continue;
		sz = strlen(sp->sp_pwdp);
		lp->l_pwdp = salloc(sz + 1);
		strcpy(lp->l_pwdp, sp->sp_pwdp);
		lp->l_lstchg = sp->sp_lstchg;
		lp->l_min = sp->sp_min;
		lp->l_max = sp->sp_max;
		lp->l_warn = sp->sp_warn;
		lp->l_inact = sp->sp_inact;
		lp->l_expire = sp->sp_expire;
		lp->l_flag = sp->sp_flag;
	}
	endspent();
#endif	/* SHADOW_PWD */
}
Exemple #12
0
int lxdm_auth_user_authenticate(LXDM_AUTH *a,const char *user,const char *pass,int type)
{
	struct passwd *pw;
	struct spwd *sp;
	char *real;
	char *enc;
	if(!user || !user[0])
	{
		g_debug("user==NULL\n");
		return AUTH_ERROR;
	}
	pw = getpwnam(user);
	endpwent();
	if(!pw)
	{
		g_debug("user %s not found\n",user);
		return AUTH_BAD_USER;
	}
	if(strstr(pw->pw_shell, "nologin"))
	{
		g_debug("user %s have nologin shell\n",user);
		return AUTH_PRIV;
	}
	if(type==AUTH_TYPE_AUTO_LOGIN && !pass)
	{
		goto out;
	}
	sp = getspnam(user);
	if( !sp )
	{
		return AUTH_FAIL;
	}
	endspent();
	real = sp->sp_pwdp;
	if( !real || !real[0] )
	{
		if( !pass || !pass[0] )
		{
			passwd_copy(&a->pw,pw);
			g_debug("user %s auth with no password ok\n",user);
			return AUTH_SUCCESS;
		}
		else
		{
			g_debug("user %s password not match\n",user);
			return AUTH_FAIL;
		}
	}
	enc = crypt(pass, real);
	if( strcmp(real, enc) )
	{
		g_debug("user %s password not match\n",user);
		return AUTH_FAIL;
	}
out:
	g_debug("user %s auth ok\n",pw->pw_name);
	passwd_copy(&a->pw,pw);
	return AUTH_SUCCESS;
}
Exemple #13
0
struct spwd * mygetspnam(const char *name){
	struct spwd *sp;
	setspent();
	while((sp=getspent()) != NULL)
		if(strcmp(name, sp->sp_namp) == 0)
			break;/*found a match*/
	endspent();
	return(sp);
}
LFUNC auth_local(char *username, char *passwd)
{
  struct passwd *pw;
  char    *xpasswd;
#ifdef SHADOW_PASSWORD
  struct spwd *spw;
#endif

  if ((pw = getpwnam(username)) == NULL) {
    endpwent();
    rc_log(LOG_NOTICE, "authentication FAILED, type local, username %s", username);
    printf(SC_LOCAL_FAILED);
    return NULL;
  }

  endpwent();

#ifdef SHADOW_PASSWORD

  if((spw = getspnam(pw->pw_name)) == NULL) {
    endspent();
    rc_log(LOG_NOTICE, "authentication FAILED, type local, username %s", username);
    printf(SC_LOCAL_FAILED);
    return NULL;
  } else {
    pw->pw_passwd = spw->sp_pwdp;
  }

  endspent();
#endif /* SHADOW_PASSWORD */

  xpasswd = crypt(passwd, pw->pw_passwd);

  if (*pw->pw_passwd == '\0' || strcmp(xpasswd, pw->pw_passwd)) {
    rc_log(LOG_NOTICE, "authentication FAILED, type local, username %s", username);
    printf(SC_LOCAL_FAILED);
    return NULL;
  }

  rc_log(LOG_NOTICE, "authentication OK, type local, username %s", username);
  printf(SC_LOCAL_OK);

  return local_login;
}
Exemple #15
0
struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[])
{
  char tmp[MAILTMPLEN];
  struct spwd *sp = NIL;
  time_t left;
  time_t now = time (0);
  struct tm *t = gmtime (&now);
  int zone = t->tm_hour * 60 + t->tm_min;
  int julian = t->tm_yday;
  t = localtime (&now);		/* get local time now */
				/* minus UTC minutes since midnight */
  zone = t->tm_hour * 60 + t->tm_min - zone;
  /* julian can be one of:
   *  36x  local time is December 31, UTC is January 1, offset -24 hours
   *    1  local time is 1 day ahead of UTC, offset +24 hours
   *    0  local time is same day as UTC, no offset
   *   -1  local time is 1 day behind UTC, offset -24 hours
   * -36x  local time is January 1, UTC is December 31, offset +24 hours
   */
  if (julian = t->tm_yday -julian)
    zone += ((julian < 0) == (abs (julian) == 1)) ? -24*60 : 24*60;
				/* days since 1/1/1970 local time */
  now = ((now /60) + zone) / (60*24);
				/* non-shadow authentication */
  if (!pw->pw_passwd || !pw->pw_passwd[0] || !pw->pw_passwd[1] ||
      strcmp (pw->pw_passwd,(char *) crypt (pass,pw->pw_passwd))) {
    /* As far as I've been able to determine, here is how the expiration
     * fields in the shadow authentication data work:
     *  lstchg	last password change date if non-negative.  If zero, the
     *		user can not log in without changing password.
     *  max	number of days a password is valid if positive
     *  warn	number of days of password expiration warning
     * The expiration day is the *last* day that the password is valid.
     */
				/* shadow authentication */
    if ((sp = getspnam (pw->pw_name)) && sp->sp_lstchg &&
	((sp->sp_lstchg < 0) || (sp->sp_max <= 0) ||
	 ((sp->sp_lstchg + sp->sp_max) >= now)) &&
	sp->sp_pwdp && sp->sp_pwdp[0] && sp->sp_pwdp[1] &&
	!strcmp (sp->sp_pwdp,(char *) crypt (pass,sp->sp_pwdp))) {
      if ((sp->sp_lstchg > 0) && (sp->sp_max > 0) &&
	  ((left = (sp->sp_lstchg + sp->sp_max) - now) <= sp->sp_warn)) {
	if (left) {
	  sprintf (tmp,"[ALERT] Password expires in %ld day(s)",(long) left);
	  mm_notify (NIL,tmp,NIL);
	}
	else mm_notify (NIL,"[ALERT] Password expires today!",WARN);
      }
      endspent ();		/* don't need shadow password data any more */
    }
    else pw = NIL;		/* password failed */
  }
  return pw;
}
static PyObject *
spwd_getspall(PyObject *self, PyObject *args)
{
    PyObject *d;
    struct spwd *p;
    if ((d = PyList_New(0)) == NULL)
        return NULL;
    setspent();
    while ((p = getspent()) != NULL) {
        PyObject *v = mkspent(p);
        if (v == NULL || PyList_Append(d, v) != 0) {
            Py_XDECREF(v);
            Py_DECREF(d);
            endspent();
            return NULL;
        }
        Py_DECREF(v);
    }
    endspent();
    return d;
}
Exemple #17
0
static void auth_shadow_cleanup()
{
#if	HAVE_ENDPWENT

	endpwent();
#endif

#if	HAVE_ENDSPENT

	endspent();
#endif
}
Exemple #18
0
int main(void)
{
    struct spwd *spwd;
    spwd = getspnam("qy");
    printf("shadow password = %s\n", spwd->sp_pwdp);

    setspent();
    while ((spwd = getspent()) != NULL) {
        printf("shadow password = %s\n", spwd->sp_pwdp);
    }
    endspent();
    return 0;
}
Exemple #19
0
static PyObject *
spwd_getspall_impl(PyObject *module)
/*[clinic end generated code: output=4fda298d6bf6d057 input=b2c84b7857d622bd]*/
{
    PyObject *d;
    struct spwd *p;
    if ((d = PyList_New(0)) == NULL)
        return NULL;
    setspent();
    while ((p = getspent()) != NULL) {
        PyObject *v = mkspent(p);
        if (v == NULL || PyList_Append(d, v) != 0) {
            Py_XDECREF(v);
            Py_DECREF(d);
            endspent();
            return NULL;
        }
        Py_DECREF(v);
    }
    endspent();
    return d;
}
int main(int argc,char* argv[]){
	struct spwd* user;
	setspent();
	while((user=getspent())!=NULL){
		printf("loginname:%s,password:%s\n",user->sp_namp,user->sp_pwdp);
	}
	endspent();
	user=getspnam("linuxmin");	
	if(user!=NULL)
		printf("loginname:%s,password:%s\n",user->sp_namp,user->sp_pwdp);
	printf("......\n");
	return 0;
}
Exemple #21
0
int main(void)
{
    struct spwd *ptr;

    setspent();
    
    while ((ptr = getspent()) != NULL)
    {
        printf("name= %s\tshaow passwd = %s\n", ptr->sp_namp, ptr->sp_pwdp);
    }

    endspent();

    return 0;
}
Exemple #22
0
/* getspnam - get a shadow entry by name */
struct spwd *getspnam(const char *name)
{
	struct spwd *sp;

	if (!name || !strlen(name))
		return NULL;

	setspent();
	while ((sp = getspent()) != NULL) {
		if (strcmp(name, sp->sp_namp) == 0)
			break;
	}
	endspent();
	return (sp);
}
Exemple #23
0
/* getspuid - get a shadow entry by uid */
struct spwd *getspuid(uid_t uid)
{
	struct spwd *sp;
	struct passwd *mypw;

	if ((mypw = getpwuid(getuid())) == NULL) {
		return (NULL);
	}
	setspent();
	while ((sp = getspent()) != NULL) {
		if (strcmp(mypw->pw_name, sp->sp_namp) == 0)
			break;
	}
	endspent();
	return (sp);
}
Exemple #24
0
static bool
verify_root_pw( const char* pw)
{
     const char* superuser = "******";
#ifdef USESHADOW
     struct spwd *spws = getspnam( superuser);
#endif
#ifdef USE_PAM
     pam_handle_t *pamh;
     int pam_error;
#endif /* USE_PAM */
     struct passwd *pws = getpwnam( superuser);
     CHECK_PTR( pws);
#ifndef USE_PAM
#ifdef USESHADOW
     // If USESHADOW is defined, kdm will work for both shadow and non
     // shadow systems
     if( spws != NULL) {
       char* tmp = pws->pw_passwd;
       pws->pw_passwd = spws->sp_pwdp;
       spws->sp_pwdp = tmp;
     }
     endspent();
#endif /* USESHADOW */
     if( strcmp( crypt( pw, pws->pw_passwd), pws->pw_passwd)) {
	  printf("Root passwd verification failed\n");
	  
	  return false;
     }
#else /* USE_PAM */
     #define PAM_BAIL \
        if (pam_error != PAM_SUCCESS) { \
	pam_end(pamh, 0); \
        return false; \
      }
     PAM_password = pw;
     pam_error = pam_start(KDE_PAM, superuser, &PAM_conversation, &pamh);
     PAM_BAIL;
     pam_error = pam_authenticate( pamh, 0);
     PAM_BAIL;
     /* OK, if we get here, the user _should_ be root */
     pam_end( pamh, PAM_SUCCESS);
#endif /* USE_PAM */
     return true;
}
Exemple #25
0
// 读取/etc/shadow文件
// 执行时sudo, 才能读取到
void op_shadow()
{
	struct spwd *sp;
	char name[] = "root";
	// 将指针移到开始位置
	setspent();
	// 获取第一条记录
	while((sp = getspent()) != NULL)
	{
		//if (strcmp(name, sp->pw_name) == 0)
		//{
		//	printf("pw_name:%s, pw_uid:%d, pw_shell:%s\n", ptr->pw_name, ptr->pw_uid, ptr->pw_shell);
		//	break;   	
		//}
		printf("sp_namp:%s, sp_pwdp:%s, sp_expire:%ld\n", sp->sp_namp, sp->sp_pwdp, sp->sp_expire);
	}
	// 结束读取
	endspent();
}
Exemple #26
0
struct passwd * ROKEN_LIB_FUNCTION
k_getpwuid (uid_t uid)
{
     struct passwd *p;

     p = getpwuid (uid);
#if defined(HAVE_GETSPNAM) && defined(HAVE_STRUCT_SPWD)
     if (p)
     {
	  struct spwd *spwd;

	  spwd = getspnam (p->pw_name);
	  if (spwd)
	       p->pw_passwd = spwd->sp_pwdp;
	  endspent ();
     }
#else
     endpwent ();
#endif
     return p;
}
Exemple #27
0
ROKEN_LIB_FUNCTION struct passwd * ROKEN_LIB_CALL
k_getpwnam (const char *user)
{
     struct passwd *p;

     p = getpwnam (user);
#if defined(HAVE_GETSPNAM) && defined(HAVE_STRUCT_SPWD)
     if(p)
     {
	  struct spwd *spwd;

	  spwd = getspnam (user);
	  if (spwd)
	       p->pw_passwd = spwd->sp_pwdp;
	  endspent ();
     }
#else
     endpwent ();
#endif
     return p;
}
Exemple #28
0
int main(int argc, char * argv[])
{
    struct spwd * sp;
    
    if(argc < 2)
    {
        printf("Usage: %s username\n", argv[0]);
        exit(-1);
    }
    setspent();
    if((sp = getspnam(argv[1])) != NULL)
    {
        printf("%s, %s\n", sp->sp_namp, sp->sp_pwdp);
    }
    setspent();
    while((sp = getspent()) != NULL)
    {
        printf("%s, %s\n", sp->sp_namp, sp->sp_pwdp);
    }
    endspent();

    return 0;
}
Exemple #29
0
static const char *
getpw(void) { /* only run as root */
	const char *rval;
	struct passwd *pw;

	if(g_pw)
		return g_pw;

	errno = 0;
	pw = getpwuid(getuid());
	if (!pw) {
		if (errno)
			die("slock: getpwuid: %s\n", strerror(errno));
		else
			die("slock: cannot retrieve password entry (make sure to suid or sgid slock)\n");
	}
	endpwent();
	rval =  pw->pw_passwd;

#if HAVE_SHADOW_H
	if (rval[0] == 'x' && rval[1] == '\0') {
		struct spwd *sp;
		sp = getspnam(getenv("USER"));
		if(!sp)
			die("slock: cannot retrieve shadow entry (make sure to suid or sgid slock)\n");
		endspent();
		rval = sp->sp_pwdp;
	}
#endif

	/* drop privileges */
	if (geteuid() == 0
	   && ((getegid() != pw->pw_gid && setgid(pw->pw_gid) < 0) || setuid(pw->pw_uid) < 0))
		die("slock: cannot drop privileges\n");
	return rval;
}
Exemple #30
0
PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
    int argc, const char **argv)
{
	params_t params;
	struct pam_response *resp;
	struct passwd *pw, fake_pw;
#ifdef HAVE_SHADOW
	struct spwd *spw;
#endif
	char *user, *oldpass, *newpass, *randompass;
	const char *reason;
	int ask_oldauthtok;
	int randomonly, enforce, retries_left, retry_wanted;
	int status;

	params = defaults;
	status = parse(&params, pamh, argc, argv);
	if (status != PAM_SUCCESS)
		return status;

	ask_oldauthtok = 0;
	if (flags & PAM_PRELIM_CHECK) {
		if (params.flags & F_ASK_OLDAUTHTOK_PRELIM)
			ask_oldauthtok = 1;
	} else
	if (flags & PAM_UPDATE_AUTHTOK) {
		if (params.flags & F_ASK_OLDAUTHTOK_UPDATE)
			ask_oldauthtok = 1;
	} else
		return PAM_SERVICE_ERR;

	if (ask_oldauthtok && getuid() != 0) {
		status = converse(pamh, PAM_PROMPT_ECHO_OFF,
		    PROMPT_OLDPASS, &resp);

		if (status == PAM_SUCCESS) {
			if (resp && resp->resp) {
				status = pam_set_item(pamh,
				    PAM_OLDAUTHTOK, resp->resp);
				_pam_drop_reply(resp, 1);
			} else
				status = PAM_AUTHTOK_RECOVERY_ERR;
		}

		if (status != PAM_SUCCESS)
			return status;
	}

	if (flags & PAM_PRELIM_CHECK)
		return status;

	status = pam_get_item(pamh, PAM_USER, (pam_item_t *)&user);
	if (status != PAM_SUCCESS)
		return status;

	status = pam_get_item(pamh, PAM_OLDAUTHTOK, (pam_item_t *)&oldpass);
	if (status != PAM_SUCCESS)
		return status;

	if (params.flags & F_NON_UNIX) {
		pw = &fake_pw;
		pw->pw_name = user;
		pw->pw_gecos = "";
	} else {
		pw = getpwnam(user);
		endpwent();
		if (!pw)
			return PAM_USER_UNKNOWN;
		if ((params.flags & F_CHECK_OLDAUTHTOK) && getuid() != 0) {
			if (!oldpass)
				status = PAM_AUTH_ERR;
			else
#ifdef HAVE_SHADOW
			if (!strcmp(pw->pw_passwd, "x")) {
				spw = getspnam(user);
				endspent();
				if (spw) {
					if (strcmp(crypt(oldpass, spw->sp_pwdp),
					    spw->sp_pwdp))
						status = PAM_AUTH_ERR;
					memset(spw->sp_pwdp, 0,
					    strlen(spw->sp_pwdp));
				} else
					status = PAM_AUTH_ERR;
			} else
#endif
			if (strcmp(crypt(oldpass, pw->pw_passwd),
			    pw->pw_passwd))
				status = PAM_AUTH_ERR;
		}
		memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
		if (status != PAM_SUCCESS)
			return status;
	}

	randomonly = params.qc.min[4] > params.qc.max;

	if (getuid() != 0)
		enforce = params.flags & F_ENFORCE_USERS;
	else
		enforce = params.flags & F_ENFORCE_ROOT;

	if (params.flags & F_USE_AUTHTOK) {
		status = pam_get_item(pamh, PAM_AUTHTOK,
		    (pam_item_t *)&newpass);
		if (status != PAM_SUCCESS)
			return status;
		if (!newpass || (check_max(&params, pamh, newpass) && enforce))
			return PAM_AUTHTOK_ERR;
		reason = _passwdqc_check(&params.qc, newpass, oldpass, pw);
		if (reason) {
			say(pamh, PAM_ERROR_MSG, MESSAGE_WEAKPASS, reason);
			if (enforce)
				status = PAM_AUTHTOK_ERR;
		}
		return status;
	}

	retries_left = params.retry;

retry:
	retry_wanted = 0;

	if (!randomonly &&
	    params.qc.passphrase_words && params.qc.min[2] <= params.qc.max)
		status = say(pamh, PAM_TEXT_INFO, MESSAGE_INTRO_BOTH);
	else
		status = say(pamh, PAM_TEXT_INFO, MESSAGE_INTRO_PASSWORD);
	if (status != PAM_SUCCESS)
		return status;

	if (!randomonly && params.qc.min[3] <= params.qc.min[4])
		status = say(pamh, PAM_TEXT_INFO, MESSAGE_EXPLAIN_PASSWORD_1,
		    params.qc.min[3] == 8 || params.qc.min[3] == 11 ? "n" : "",
		    params.qc.min[3]);
	else
	if (!randomonly)
		status = say(pamh, PAM_TEXT_INFO, MESSAGE_EXPLAIN_PASSWORD_2,
		    params.qc.min[3] == 8 || params.qc.min[3] == 11 ? "n" : "",
		    params.qc.min[3],
		    params.qc.min[4] == 8 || params.qc.min[4] == 11 ? "n" : "",
		    params.qc.min[4]);
	if (status != PAM_SUCCESS)
		return status;

	if (!randomonly &&
	    params.qc.passphrase_words &&
	    params.qc.min[2] <= params.qc.max) {
		status = say(pamh, PAM_TEXT_INFO, MESSAGE_EXPLAIN_PASSPHRASE,
		    params.qc.passphrase_words,
		    params.qc.min[2], params.qc.max);
		if (status != PAM_SUCCESS)
			return status;
	}

	randompass = _passwdqc_random(&params.qc);
	if (randompass) {
		status = say(pamh, PAM_TEXT_INFO, randomonly ?
		    MESSAGE_RANDOMONLY : MESSAGE_RANDOM, randompass);
		if (status != PAM_SUCCESS) {
			_pam_overwrite(randompass);
			randompass = NULL;
		}
	} else
	if (randomonly) {
		say(pamh, PAM_ERROR_MSG, getuid() != 0 ?
		    MESSAGE_MISCONFIGURED : MESSAGE_RANDOMFAILED);
		return PAM_AUTHTOK_ERR;
	}

	status = converse(pamh, PAM_PROMPT_ECHO_OFF, PROMPT_NEWPASS1, &resp);
	if (status == PAM_SUCCESS && (!resp || !resp->resp))
		status = PAM_AUTHTOK_ERR;

	if (status != PAM_SUCCESS) {
		if (randompass) _pam_overwrite(randompass);
		return status;
	}

	newpass = strdup(resp->resp);

	_pam_drop_reply(resp, 1);

	if (!newpass) {
		if (randompass) _pam_overwrite(randompass);
		return PAM_AUTHTOK_ERR;
	}

	if (check_max(&params, pamh, newpass) && enforce) {
		status = PAM_AUTHTOK_ERR;
		retry_wanted = 1;
	}

	reason = NULL;
	if (status == PAM_SUCCESS &&
	    (!randompass || !strstr(newpass, randompass)) &&
	    (randomonly ||
	    (reason = _passwdqc_check(&params.qc, newpass, oldpass, pw)))) {
		if (randomonly)
			say(pamh, PAM_ERROR_MSG, MESSAGE_NOTRANDOM);
		else
			say(pamh, PAM_ERROR_MSG, MESSAGE_WEAKPASS, reason);
		if (enforce) {
			status = PAM_AUTHTOK_ERR;
			retry_wanted = 1;
		}
	}

	if (status == PAM_SUCCESS)
		status = converse(pamh, PAM_PROMPT_ECHO_OFF,
		    PROMPT_NEWPASS2, &resp);
	if (status == PAM_SUCCESS) {
		if (resp && resp->resp) {
			if (strcmp(newpass, resp->resp)) {
				status = say(pamh,
				    PAM_ERROR_MSG, MESSAGE_MISTYPED);
				if (status == PAM_SUCCESS) {
					status = PAM_AUTHTOK_ERR;
					retry_wanted = 1;
				}
			}
			_pam_drop_reply(resp, 1);
		} else
			status = PAM_AUTHTOK_ERR;
	}

	if (status == PAM_SUCCESS)
		status = pam_set_item(pamh, PAM_AUTHTOK, newpass);

	if (randompass) _pam_overwrite(randompass);
	_pam_overwrite(newpass);
	free(newpass);

	if (retry_wanted && --retries_left > 0) {
		status = say(pamh, PAM_TEXT_INFO, MESSAGE_RETRY);
		if (status == PAM_SUCCESS)
			goto retry;
	}

	return status;
}