/* Copyright (C) 1999 Beau Kuiper

   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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include "config.h"
#include "auth.h"
#include <string.h>
#include <sys/time.h>
#include <pwd.h>
#include "valid.h"

/* This file contains code to autheticate against smb servers */

typedef struct 
{
	struct passwd *passent;
	char *domainname;
	char *primaryname;
	char *secondaryname;
} PASSWDSTRUCT;

void freehandle(void *handle)
{
	PASSWDSTRUCT *h = (PASSWDSTRUCT *)handle;
	if (h->domainname) freewrapper(h->domainname);
	if (h->primaryname) freewrapper(h->primaryname);
	if (h->secondaryname) freewrapper(h->secondaryname);

	freewrapper(handle);
}

void *gethandle(void *peer, void *tset, char *username, int *err)
{
	PASSWDSTRUCT *newhandle;
	int section, localpwd;
	char *authuser = NULL;

	section = auth_getcursectionid(peer);
	newhandle = (PASSWDSTRUCT *)mallocwrapper(sizeof(PASSWDSTRUCT));

	newhandle->domainname = mktokconfstr(tset, section, "smb_domain", NULL);
	newhandle->primaryname = mktokconfstr(tset, section, "smb_primary", NULL);
	newhandle->secondaryname = mktokconfstr(tset, section, "smb_secondary", NULL);
	
	if (newhandle->domainname == NULL)
	{
		log_addentry(MYLOG_INFO, NULL, "libauthsmb REQUIRES smb_domain to supply domain to authenticate against!");
		goto error;
	}
	
	if (newhandle->primaryname == NULL)
	{
		log_addentry(MYLOG_INFO, NULL, "libauthsmb REQUIRES smb_primary to supply host to authenticate against!");
		goto error;
	}

	if (newhandle->secondaryname == NULL)
		newhandle->secondaryname = strdupwrapper(newhandle->primaryname);
			
	authuser = mktokconfstr(tset, section, "smb_localuser", NULL);

	if (authuser)
	{
		newhandle->passent = getpwnam(authuser);
		if (newhandle->passent == NULL)
		{
			log_giveentry(MYLOG_INFO, NULL, safe_snprintf("libauthsmb couldn't find local username '%s'", authuser));
			goto error;
		}
	}
	else
	{
		newhandle->passent = getpwnam(username);
		if (newhandle->passent == NULL)
			goto errornouser;
	}

	if (authuser) freewrapper(authuser);	
	*err = AUTH_OK;
	return(newhandle);

error:
	*err = AUTH_ERROR;
	goto cleanuperror;

errornouser:
	*err = AUTH_USERNKNOW;

cleanuperror:
	freehandle((void *)newhandle);
	if (authuser) freewrapper(authuser);
	return(NULL);
}

int chkpasswd(void *handle, char *password, char **errmsg)
{
	PASSWDSTRUCT *h = (PASSWDSTRUCT *)handle;
	int result;

	result = Valid_User(h->passent->pw_name, password, h->primaryname,
		 h->secondaryname, h->domainname);
	
	switch (result)
	{
		case 0:
			return(TRUE);
		case 1:
		case 2:
			log_giveentry(MYLOG_INFO, NULL, 
				safe_snprintf("smbauth - Domain '%s' unavailable",
				h->domainname));
		case 3:
		default:
			return(FALSE);
	}			
	return(FALSE);
}

char *gethomedir(void *h)
{
	return(((PASSWDSTRUCT *)h)->passent->pw_dir);
}

char *getrootdir(void *h)
{
	return("/");
}

uid_t getuseruid(void *h)
{
	return(((PASSWDSTRUCT *)h)->passent->pw_uid);
}

gid_t getusergid(void *h)
{
	return(((PASSWDSTRUCT *)h)->passent->pw_gid);
}

gid_t *getusersupgid(void *h)
{
	return(getusergrouplist(((PASSWDSTRUCT *)h)->passent->pw_name));
}
