/*
 * ----------------------------------------------------------------
 * Night Light IRC Proxy - Client Authentication
 * ----------------------------------------------------------------
 * Copyright (C) 1997-2007 Jonas Kvinge <jonas@night-light.net>
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Last modified by:
 * Jonas Kvinge (29.11.2007)
 *
 */

#define CLIENT_AUTH_C

#define NEED_SYS_TYPES_H 1		/* Extra types */
#define NEED_SYS_PARAM_H 1		/* Some systems need this */
#define NEED_LIMITS_H 0			/* Kernel limits */
#define NEED_STDARG_H 1			/* va_list, etc */
#define NEED_ERRNO_H 1			/* errno */
#define NEED_CTYPE_H 0			/* isdigit(), etc */
#define NEED_NETINET_IN_H 0		/* in_addr, sockaddr_in, etc */
#define NEED_ARPA_INET_H 0		/* inet_ntoa(), inet_aton(), etc */
#define NEED_STDIO_H 1			/* Standard C UNIX functions */
#define NEED_STDLIB_H 1			/* malloc(), exit(), atoi(), etc */
#define NEED_TIME_H 1			/* time(), etc */
#define NEED_SYSCTL_H 0			/* sysctl(), etc */
#define NEED_SYS_STAT_H 0		/* chmod(), mkdir(), etc */
#define NEED_SYS_UIO_H 0		/* iovec, etc */
#define NEED_FCNTL_H 1			/* open(), creat(), fcntl(), etc */
#define NEED_SYS_IOCTL_H 0		/* ioctl(), etc */
#define NEED_SYS_FILIO_H 0		/* Solaris need this for ioctl(), etc */
#define NEED_UNISTD_H 1			/* Unix standard functions */
#define NEED_STRING_H 1			/* C string functions */
#define NEED_SIGNAL_H 0			/* Signal functions */
#define NEED_SYS_SOCKET_H 0		/* Socket functions */
#define NEED_NETDB_H 0			/* Network database functions */
#define NEED_ARPA_NAMESER_H 0		/* Nameserver definitions */
#define NEED_GETUSERPW_HEADERS 1 	/* Functions to retrive system passwords */

#include "includes.h"

#include "conf.h"
#include "client_auth.h"
#include "matchpass.h"

#include "user_conf.h"

/* VARIABLES - JONAS (31.07.2001) */

extern struct Conf_Struct ConfS;
extern unsigned short int Root;
extern struct UserConf_Struct *UserConf_Head;
extern uid_t UID_Current;
extern uid_t EUID_Current;
extern uid_t UID_Normal;
extern uid_t EUID_Normal;

/* CLIENT_AUTHCHECK FUNCTION - JONAS (27.02.2002) */

unsigned short int client_authcheck(char *UserPT, char *PassPT) {

  struct UserConf_Struct *UserConf = NULL;
  char *CryptPassPT = NULL;

  assert(UserPT != NULL);
  assert(PassPT != NULL);

  if ((ConfS.UnixPasswd == FALSE) || (Root == FALSE)) {
    for (UserConf = UserConf_Head ; UserConf != NULL ; UserConf = UserConf->Next) {
      if ((strcmp(UserConf->User, UserPT) == FALSE) && (matchpass(UserConf->Pass, PassPT) == TRUE)) {
        aerrno = AESUCCESS;
        return(AESUCCESS);
      }
    }
    aerrno = AENOMATCH;
    return(AENOMATCH);
  }

  if ((UID_Current == 0) && (EUID_Current != 0)) { sysseteuid(0); }

  #if HAVE_GETPWNAM && !HAVE_GETSPNAM /* Traditional UNIX */

#if 1
    #warning "Using getpwnam() - Traditional UNIX -- THIS NOT A ERROR --"
#endif

    FAKELOOP {
      struct passwd *PasswdPT = NULL;

      PasswdPT = getpwnam(UserPT);
      if (PasswdPT == NULL) {
        if (EUID_Current != EUID_Normal) { sysseteuidnormal(); }
        aerrno = AENOMATCH;
        return(AENOMATCH);
      }
      CryptPassPT = PasswdPT->pw_passwd;
    }

  #elif HAVE_GETSPNAM /* Sun Shadow System */

#if 1
    #warning "Using getspnam() - Sun Shadow System -- THIS NOT A ERROR --"
#endif

    FAKELOOP {
      struct spwd *PasswdPT = NULL;

      PasswdPT = getspnam(UserPT);
      if (PasswdPT == NULL) {
        if (EUID_Current != EUID_Normal) { sysseteuidnormal(); }
        aerrno = AENOMATCH;
        return(AENOMATCH);
      }
      CryptPassPT = PasswdPT->sp_pwdp;
    }

  #elif HAVE_GETUSERPW /* AIX */

#if 1
    #warning "Using getuserpw() - AIX -- THIS NOT A ERROR --"
#endif

    FAKELOOP {
      struct userpw *PasswdPT = NULL;

      PasswdPT = getuserpw(UserPT);
      if (PasswdPT == NULL) {
        if (EUID_Current != EUID_Normal) { sysseteuidnormal(); }
        aerrno = AENOMATCH;
        return(AENOMATCH);
      }
      CryptPassPT = Passwd->upw_passwd;
    }

  #elif HAVE_GETSPWNAM /* HP UNIX */

#if 1
    #warning "Using getspwnam() HP UNIX -- THIS NOT A ERROR --"
#endif

    FAKELOOP {
      struct pr_passwd *PasswdPT = NULL;

      PasswdPT = getspwnam(UserPT);
      if (PasswdPT == NULL) {
        if (EUID_Current != EUID_Normal) { sysseteuidnormal(); }
        aerrno = AENOMATCH;
        return(AENOMATCH);
      }
      CryptPassPT = PasswdPT->ufld.fd_encrypt;
    }

  #else

    #warning "UNIX passwd authentication not available on this system -- THIS NOT A ERROR --"

  #endif

  if (EUID_Current != EUID_Normal) { sysseteuidnormal(); }

  assert(CryptPassPT != NULL);

  if (matchpass(CryptPassPT, PassPT) == TRUE) {
     aerrno = AESUCCESS;
     return(AESUCCESS);
  }
  else {
    aerrno = AENOMATCH;
    return(AENOMATCH);
  }

  aerrno = AENOMATCH;
  return(AENOMATCH);

}



syntax highlighted by Code2HTML, v. 0.9.1