/************************************************************************
 *	Modify to taste in order to comply with your authentication	*
 *	(e.g. Radius or shadow passwd) and mailbox conventions		*
 *									*
 *	You have the liberty to redefine the identity typedef in	*
 *	any way you see fit, so that it can hold state information	*
 *	you need to authenticate your users				*
 *									*
 *	Copyright (c) 1996, S.R. van den Berg, The Netherlands		*
 *	#include "../README"						*
 ************************************************************************/
#ifdef RCS
static /*const*/char rcsid[]=
 "$Id: authenticate.c,v 1.6 1996/12/26 17:23:39 srb Exp $";
#endif

#include "config.h"

#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>

#ifdef SHADOW_PASSWD
#include <shadow.h>
#endif

#include "cucipop.h"
#include "authenticate.h"

#ifndef SPOOLDIR
#define SPOOLDIR "/var/spool/mail/"
#endif
#ifndef STRLEN
#define STRLEN(x)	(sizeof(x)-1)
#endif

struct auth_identity
{ const struct passwd*pw;
  char*mbox;
  int sock;
};

static const struct passwd*cgetpwnam(const char*user,const int sock)
{ return getpwnam(user);
}

const auth_identity*auth_finduser(char*user,const int sock)
{ static auth_identity authi;		      /* reuse copy, only one active */
  if(!(authi.pw=cgetpwnam(user,sock)))		  /* /etc/passwd user lookup */
   { char*p;
     if(p=strchr(user,'@'))		  /* does the username contain an @? */
	*p='\0';		      /* clueless user using the mailaddress */
     castlower(user);	      /* make it all lowercase (luser problem no. 1) */
     if(!(authi.pw=cgetpwnam(user,sock)))	/* ok, be nice and try again */
	return 0;		       /* sorry, no such user on this planet */
   }
  authi.sock=sock;
  return &authi;			  /* user found, one down, one to go */
}

uid_t auth_whatuid(const auth_identity*pass)
{ return pass->pw->pw_uid;
}

const int auth_checkpassword(const auth_identity*pass,const char*pw,
 const int allowemptypw)
{ const char*rpw;
  rpw=pass->pw->pw_passwd;
#ifdef SHADOW_PASSWD
  ;{ struct spwd*spwd;
     if(spwd=getspnam(pass->pw->pw_name))
	rpw=spwd->sp_pwdp;
   }
#endif
  if(!*rpw)
     return allowemptypw;
  return !strcmp(rpw,crypt(pw,rpw));
}

char*auth_getsecret(const auth_identity*pass)
{ return 0;	       /* no standard way to get a secret, add function here */
}

const char*auth_mailboxname(auth_identity*pass)
{ if(pass->mbox)
     free(pass->mbox);
  if(!(pass->mbox=malloc(STRLEN(SPOOLDIR)+strlen(pass->pw->pw_name))))
     return "";
  strcpy(pass->mbox,SPOOLDIR);
  strcpy(pass->mbox+STRLEN(SPOOLDIR),pass->pw->pw_name);
  return pass->mbox;
}
