Exemple #1
0
static char *_get_pw_info(pool *p, const char *u, time_t *lstchg, time_t *min,
    time_t *max, time_t *warn, time_t *inact, time_t *expire) {
  char *cpw = NULL;
#if defined(HAVE_GETPRPWENT) || defined(COMSEC)
  struct pr_passwd *prpw;
#endif
#if !defined(HAVE_GETPRPWENT) || defined(COMSEC)
  struct passwd *pw;
#endif

 /* Some platforms (i.e. BSD) provide "transparent" shadowing, which
  * requires that we are root in order to have the password member
  * filled in.
  */

  PRIVS_ROOT
#if !defined(HAVE_GETPRPWENT) || defined(COMSEC)
# ifdef COMSEC
  if (!iscomsec()) {
# endif /* COMSEC */
  endpwent();
#if defined(BSDI3) || defined(BSDI4)
  /* endpwent() seems to be buggy on BSDI3.1 (is this true for 4.0?)
   * setpassent(0) _seems_ to do the same thing, however this conflicts
   * with the man page documented behavior.  Argh, why do all the bsds
   * have to be different in this area (except OpenBSD, grin).
   */
  setpassent(0);
#else /* BSDI3 || BSDI4 */
  setpwent();
#endif /* BSDI3 || BSDI4 */

  pw = getpwnam(u);
  if (pw) {
    cpw = pstrdup(p, pw->pw_passwd);

    if (lstchg)
      *lstchg = (time_t) -1;

    if (min)
      *min = (time_t) -1;

    if (max)
      *max = (time_t) -1;

    if (warn)
      *warn = (time_t) -1;

    if (inact)
      *inact = (time_t) -1;

    if (expire)
      *expire = (time_t) -1;
  }

  endpwent();
#ifdef COMSEC
  } else {
#endif /* COMSEC */
#endif /* !HAVE_GETPRWENT or COMSEC */

#if defined(HAVE_GETPRPWENT) || defined(COMSEC)
  endprpwent();
  setprpwent();

  prpw = getprpwnam((char *) u);

  if (prpw) {
    cpw = pstrdup(p, prpw->ufld.fd_encrypt);

    if (lstchg)
      *lstchg = (time_t) -1;

    if (min)
      *min = prpw->ufld.fd_min;

    if (max)
      *max = (time_t) -1;

    if (warn)
      *warn = (time_t) -1;

    if (inact)
      *inact = (time_t) -1;

    if (expire)
      *expire = prpw->ufld.fd_expire;
  }

  endprpwent();
#ifdef COMSEC
  }
#endif /* COMSEC */
#endif /* HAVE_GETPRPWENT or COMSEC */

  PRIVS_RELINQUISH
#if defined(BSDI3) || defined(BSDI4)
  setpassent(1);
#endif
  return cpw;
}
Exemple #2
0
/* As above, but uses struct passwd. This function does all the work. */
SshUser ssh_user_initialize_with_pw(struct passwd *pw, Boolean privileged)
{
  SshUser uc;

  char correct_passwd[200];

  if (!pw)
    return NULL;
  
  uc = ssh_xcalloc(1, sizeof(*uc));

  uc->name = ssh_xstrdup(pw->pw_name);
  uc->dir = ssh_xstrdup(pw->pw_dir);
  uc->uid = pw->pw_uid;
  uc->gid = pw->pw_gid;

  if (strcmp(pw->pw_shell, "") == 0)
    {
      uc->shell = ssh_xstrdup("/bin/sh");
    }
  else
    {    
      uc->shell = ssh_xstrdup(pw->pw_shell);
    }
  
  if (privileged)
    {
      
      /* Save the encrypted password. */
      strncpy(correct_passwd, pw->pw_passwd, sizeof(correct_passwd));

#ifdef HAVE_SIA
      /* pr->pw_passwd may not be the real encrypted password (it won't be
         under Enhanced Security), but we don't care because we never look at
         uc->correct_encrypted_passwd.  We let my_sia_validate_user() do all
         the work instead. */
#else /* HAVE_SIA */
      /* If we have shadow passwords, lookup the real encrypted password from
         the shadow file, and replace the saved encrypted password with the
         real encrypted password. */
#if defined(HAVE_SCO_ETC_SHADOW) || defined(HAVE_HPUX_TCB_AUTH)
      {
        struct pr_passwd *pr = getprpwnam(ssh_user_name(uc));
        pr = getprpwnam(ssh_user_name(uc));
        if (pr)
          strncpy(correct_passwd, pr->ufld.fd_encrypt, sizeof(correct_passwd));
        endprpwent();
      }
#else /* defined(HAVE_SCO_ETC_SHADOW) || defined(HAVE_HPUX_TCB_AUTH) */
#ifdef HAVE_ETC_SHADOW
      {
        struct spwd *sp = getspnam(ssh_user_name(uc));
#if defined(SECURE_RPC) && defined(NIS_PLUS)
        if (geteuid() == UID_ROOT && ssh_user_uid(uc) != UID_ROOT &&
            (!sp || !sp->sp_pwdp || !strcmp(sp->sp_pwdp,"*NP*")))
          if (seteuid(ssh_user_uid(uc)) >= 0)
            {
              sp = getspnam(ssh_user_name(uc)); /* retry as user */   
              seteuid(UID_ROOT);
            }
#endif /* SECURE_RPC && NIS_PLUS */
        if (sp)
          strncpy(correct_passwd, sp->sp_pwdp, sizeof(correct_passwd));
        endspent();
      }
#else /* HAVE_ETC_SHADOW */
#ifdef HAVE_ETC_SECURITY_PASSWD_ADJUNCT
      {
        struct passwd_adjunct *sp = getpwanam(ssh_user_name(uc));
        if (sp)
          strncpy(correct_passwd, sp->pwa_passwd, sizeof(correct_passwd));
        endpwaent();
      }
#else /* HAVE_ETC_SECURITY_PASSWD_ADJUNCT */
#ifdef HAVE_ETC_SECURITY_PASSWD /* AIX, at least.  Is there an easier way? */
      {
        FILE *f;
        char line[1024], looking_for_user[200], *cp;
        int found_user = 0;
        f = fopen("/etc/security/passwd", "r");
        if (f)
          {
            /* XXX: user next line was server_user, is this OK? */
            snprintf(looking_for_user, sizeof(looking_for_user), "%.190s:", user);
            while (fgets(line, sizeof(line), f))
              {
                if (strchr(line, '\n'))
                  *strchr(line, '\n') = 0;
                if (strcmp(line, looking_for_user) == 0)
                  found_user = 1;
                else
                  if (line[0] != '\t' && line[0] != ' ')
                    found_user = 0;
                  else
                    if (found_user)
                      {
                        for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
                          ;
                        if (strncmp(cp, "password = "******"password = "******"password = "), 
                                    sizeof(correct_passwd));
                            correct_passwd[sizeof(correct_passwd) - 1] = 0;
                            break;
                          }
                      }
              }
            fclose(f);
          }
      }
#endif /* HAVE_ETC_SECURITY_PASSWD */
#endif /* HAVE_ETC_SECURITY_PASSWD_ADJUNCT */
#endif /* HAVE_ETC_SHADOW */
#endif /* HAVE_SCO_ETC_SHADOW */
#endif /* HAVE_SIA */

      uc->correct_encrypted_passwd = ssh_xstrdup(correct_passwd);

      uc->login_allowed = ssh_login_permitted(uc->name, uc);
    }
  else /* !privileged */
    {
      uc->correct_encrypted_passwd = NULL;
      uc->login_allowed = TRUE;
      uc->password_needs_change = FALSE;
    }
  
  /* XXX should check password expirations (some systems already do this in
     ssh_login_permitted). */
  
  return uc;
}