/*
 * Copyright (c) 2003-2007, OpenFWTK Development Group
 * All rights reserved. See LICENSE.
 */

#include	<stdio.h>
#include	<stdlib.h>
#include	<unistd.h>
#include	<sys/types.h>
#include	<sys/file.h>
#ifndef DB4
#include	<ndbm.h>
#else
#define         DB_DBM_HSEARCH  1
#include	<db.h>
#endif
#include	<syslog.h>

#include        <string.h>
#include        <strings.h>


#include	"firewall.h"
#include	"auth.h"
#include	"authdb.h"
#include        "gp_list.h"

static	char*	moduleId ATTR_UNUSED = "$Id: authload.c,v 1.9 2007/09/10 02:49:12 arkenoi Exp $";

static	int	ln = 0;
static	Cfg	*confp;
static	int	tin;
extern  size_t  strlcpy(char*,const char*,size_t);

static	int	getarec(char*,Auth*);

static	char *
nlgets(b,bs,fd)
char	*b;
int	bs;
FILE	*fd;
{
	char		*p;

	if(fgets(b,bs,fd) == (char *)0)
		return((char *)0);
	if((p = strrchr(b,'\n')) != (char *)0)
		*p = '\0';
	return(b);
}


int
main(ac,av)
int	ac;
char	*av[];
{
	Auth	ab;
	char	user[128];
	char	buf[MAX_STR];
	int	recs = 0;

	tin = isatty(2);
	if((confp = cfg_read("authsrv")) == (Cfg *)-1) {
		fprintf(stderr,"Warning: cannot read configuration file\n");
		confp = (Cfg *)0;
	}

	if(auth_dbconfig(confp) || auth_dbopen()) {
		fprintf(stderr,"Cannot open auth database\n");
		exit(1);
	}
	if(nlgets(buf,sizeof(buf),stdin) == (char *)0)
		return(0);
	if(buf[0] != '\0') {
		fprintf(stderr,"bad format: missing leading blank line.\n");
		return(0);
	}
	ln++;

	while(getarec(user,&ab)) {
		if(auth_dbputu(user,&ab)) {
			fprintf(stderr,"Cannot write record\n");
			exit(1);
		}
		recs++;
		if(tin)
			fprintf(stderr,".");
	}

	auth_dbclose();
	if(tin)
		fprintf(stderr,"\n%d records loaded\n",recs);
	exit(0);
}

static int
getarec(u,a)
char	*u;
Auth	*a;
{
	char	buf[MAX_STR];
	int i;
	char *gflgs;
	char *gp_start, *gp_end, *str_end;

	bzero(a,sizeof(Auth));
	*u = '\0';

	while(nlgets(buf,sizeof(buf),stdin) && *buf) {
		ln++;
		if(!strncmp(buf,"user=",5)) 
			strlcpy(u,&buf[5],128);
		else if(!strncmp(buf,"longname=",9)) 
			strlcpy(a->ln,&buf[9],AUTH_LNSIZ);
		else if(!strncmp(buf,"group=",6)) {
			gp_end = &buf[5];
        		str_end = &buf[strlen(buf)];
			for(i=0;;i++)  {
          			gp_start = gp_end + 1;
				fprintf(stderr,"raw %s\n",gp_start);
	  			gp_end = index(gp_start, ' ');	   
	  			gp_end = gp_end ? gp_end : str_end;
	  			*gp_end = '\0';

	  			if(i >= AUTH_GNUM) {
		  			fprintf(stderr,"bad format: number of groups (%d) exceeds maximum (%d), line %d\n",i, AUTH_GNUM,ln);
		  			return(0);
	  			}

	  			if(gp_start >= str_end)  {
	    				a->gp[i].name[0] = '\0';  	     
	    				break;
	  			}
	  			if((gflgs = index(gp_start, ':')) == NULL) {
					a->gp[i].flgs = 0;
	  			} else {	

	  				*gflgs++ = '\0';
   	  				sscanf(gflgs,"%o",(unsigned int*)&(a->gp[i].flgs));
				}
	  			strlcpy(a->gp[i].name,gp_start,AUTH_GSIZ);
			}

		} else if(!strncmp(buf,"pass=",5)) 
			strlcpy(a->pw,&buf[5],AUTH_PWSIZ);
		else if(!strncmp(buf,"flags=",6))
			sscanf(&buf[6],"%o",(unsigned int*) &(a->flgs));
		else if(!strncmp(buf,"bad_count=",10)) 
			sscanf(&buf[10],"%d",&(a->bcnt));
		else if(!strncmp(buf,"proto=",6)) 
			a->atyp = buf[6];
		else if(!strncmp(buf,"last=",5)) 
			a->last = atol(&buf[5]);
		else if(!strncmp(buf,"lastpw=",7)) 
			a->lastpw = atol(&buf[7]);
	}
	/*
	 * Check for old auth database dump.
	 * If there is no flags, then group is single (check!) and GWIZ flags
	 * is stored separately, retreive.
	 */
	if (!gflgs && (a->flgs & AUTHFLG_GWIZ) && !(a->gp[1].name[0])) 
		a->gp[0].flgs |= AUTHFLG_GWIZ;
	if (*u)
		return(1);
	else
		return(0);
}
