/* to be conditionally included into passwd.c */

/* Returns NULL on failure, or the struct passwd
 * on success.
 * Note that this routine will very much NOT validate
 * root; doing so could lead to security problems with
 * letting root in on unsecure lines, or people trying
 * to hack by guessing somewhere failures won't be logged.
 */
static struct passwd *unix_validate(char *uname, char *passwd) {
  char salt[3];  /* 2 chars and null */
  char *cryp=NULL;	/* crypted guess (passwd) */
  char *pwfromdisk=NULL;  /* crypted actual pw */

  struct passwd* ppw=NULL;
#ifdef USE_SHADOW
  struct spwd *sppw=NULL;
#endif

  if (0 == strcasecmp(uname, "root"))
    return NULL;

  ppw = (struct passwd *) slf_getpwnam (uname);
  if (ppw == NULL)
    return NULL;

#ifndef USE_SHADOW

  pwfromdisk = ppw->pw_passwd;	/* no shadow support please */

#else

  /* check for normal non-"x" password even if compiled w/ shadow support,
   * in case shadow was not included, or currently not on.
   * (pwconv/pwunconv ran)
   */

  if (0 == strcmp("x", ppw->pw_passwd))
  {
    sppw = getspnam (uname);
    /*  printf("L75: getspname got %p\n", sppw); */
    if (sppw == NULL)
      return NULL;
    pwfromdisk = sppw->sp_pwdp;		/* get from shadow pw file */
  } else {
    pwfromdisk = ppw->pw_passwd;	/* not shadowed */
  }
#endif

  /* printf("passwd.c:80: passwd is %s\n", pwfromdisk); */

  strncpy (salt, pwfromdisk, 2);
  salt[2] = '\0';
  cryp = (char *) crypt (passwd, salt);
  memset (passwd, '\0', 250); /* null the plaintext, for security */
  if (strcmp (pwfromdisk, cryp))
    return NULL;
  else
    return ppw;
}
