/*
 * ++Copyright Released Product++
 *
 * Copyright (c) 1994, 1995 Sources of Supply Corporation ("SOS").
 * All rights reserved.
 *
 * The SOS Released Product License Agreement specifies the terms and
 * conditions for redistribution.  You may find the License Agreement
 * in the file LICENSE.
 *
 * SOS Corporation
 * 461 5th Ave.; 16th floor
 * New York, NY 10017
 *
 * +1 800 SOS UNIX
 * <sos-info@soscorp.com>
 *
 * --Copyright Released Product--
 */

/*
 * Internal information for local mode library
 */

#ifndef _bs_readconf_h
#define _bs_readconf_h


#include "unix_decl.h"

/* CLC stuff for hash tables and linked lists  */
#include <dict.h>
#include <dll.h>
#include <ht.h>

/* 
 * Users should define this before compiling.
 */
#define BS_ACL_CONF "/etc/bs.acl.conf"
#define BS_ACL_CONF_ENV "BS_ACL_CONF"

#define SEC_IN_DAY 86400


/*
 * data elements in time/addr/serv/group based hash tables
 *
 * pointer to index and pointer to linked list of values
 */
struct FirstLevel_t
  {
    char *key;			/* Index */
    dict_h info;		/* Linked list of elements */
  };

/*
 * Common element structure holding
 * a datum (pointer to structure or meta info)
 */
struct element_t
  {
    union
      {
	char *meta;
	struct timeinfo_t *time;
	struct dateinfo_t *date;
	struct addrinfo_t *addr;
	struct servinfo_t *serv;
	struct groupinfo_t *group;
	void *generic;
      }
    ptr;
    unsigned char meta:1;	/* Meta information (pseudo pointer) */
    unsigned char neg:1;	/* Is this a negative (fail on match) entry? */
  };

/*
 * Bitfield describing hours in week allowable.
 *
 * Kinda ugly and limiting, but it provides fast matches
 */
struct timeinfo_t
  {
    unsigned int alignment:1;	/* With luck... */
    unsigned int day:7;
    unsigned int hour:24;
  };

struct dateinfo_t
  {
    unsigned int days;		/* Days since the epoch */
  };

/*
 * Address range
 */
struct addrinfo_t
  {
    struct in_addr Primary;
    struct in_addr Mask;
  };

/* Service number */
struct servinfo_t
  {
    int service;
  };

/* Group info */
struct groupinfo_t
  {
    char *metatime;
    char *metadate;
    char *srcmetaaddr;
    char *srcmetaserv;
    char *dstmetaaddr;
    char *dstmetaserv;
  };

/* User info */
struct userinfo_t
  {
    char *user;			/* User identifier */
    int ena;			/* Enabled bit */
    char *auth;			/* Authenticator type */
    char *acode;		/* Authenticator code */
    char *group;		/* Group of user */
    time_t create;		/* Creation date */
    time_t last;		/* Last modification date */
    time_t expire;		/* Expiration date */
    char *contact;		/* email address of person */
    char *responsible;		/* email address of responsible user */
    char *GCOS;			/* GCOS (Name) field */
    char *comment;		/* Comment (GCOS?) */
  };

/* File info */
struct fileinfo_t
  {
    char *file;			/* File name */
    struct stat buf;		/* Inode information */
  };

/* Auth info */
struct auth_t
  {
    char *key;			/* Short auth name */
    char *name;			/* Long auth name */
    /*
     * Pointers to authentication functions
     */

    /* Get the user's challenge */
    int (*challenge) (char *user, char *acode, u_int * nextstate, u_int * req_input,
		      sos_string * outbuf, sos_string * inbuf);

    /* Check the user's password */
    int (*authenticate) (char *user, char *acode, u_int * nextstate, u_int * req_input,
			 sos_string * outbuf, sos_string * inbuf);

    /* Change password (if makes sense) */
    int (*passwd) (char *user, char *acode, u_int * nextstate, u_int * req_input,
		   sos_string * outbuf, sos_string * inbuf);

    /* Generic state engine--does anything and everything that is complicated */
    int (*state) (char *user, char *acode, u_int * nextstate, u_int * req_input,
		  sos_string * outbuf, sos_string * inbuf);

    /* All inclusive cleanup routine (MUST be called after every authentication session) */
    void (*cleanup) (char *user, char *acode);

  };

extern char *configfile;
extern char string_buf[];

/*
 * Interface Routines
 */

/* other functions */
extern int readconfig(char *file);
extern int resetconfiginit();
extern int bs_isconfig();
extern int unlinkACL();
extern int unlinkFiles();

/* Hash tables for various identifiers */
extern dict_h TimeTbl, DateTbl, AddrTbl, ServTbl, GroupTbl, UserTbl, FileTbl;
extern struct ht_args TimeSize, DateSize, AddrSize, ServSize, GroupSize,
  UserSize, FileSize;

/* Parse info needed by writeconf */
extern struct FirstLevel_t ANY;

#define FIRSTANY &ANY

/* prototypes */
extern mystrcmp(char **, char **);
extern mykeycmp(char *, char **);
extern dprintf(const char *,...);
extern ht_val hashfstr(char *);
extern ht_val phashfstr(char **);
extern struct auth_t *findauth();

/* authenticators */
#ifdef NULL_AUTH
extern int null_challenge(char *user, char *acode, u_int * nextstate, u_int * req_input,
			  sos_string * outbuf, sos_string * inbuf);
extern int null_auth(char *user, char *acode, u_int * nextstate, u_int * req_input,
		     sos_string * outbuf, sos_string * inbuf);
extern int null_passwd(char *user, char *acode, u_int * nextstate, u_int * req_input,
		       sos_string * outbuf, sos_string * inbuf);
extern int null_state(char *user, char *acode, u_int * nextstate, u_int * req_input,
		      sos_string * outbuf, sos_string * inbuf);
extern void null_cleanup(char *user, char *acode);

#endif				/*NULL_AUTH */
#ifdef TEST_AUTH
extern int test_challenge(char *user, char *acode, u_int * nextstate, u_int * req_input,
			  sos_string * outbuf, sos_string * inbuf);
extern int test_auth(char *user, char *acode, u_int * nextstate, u_int * req_input,
		     sos_string * outbuf, sos_string * inbuf);
extern int test_passwd(char *user, char *acode, u_int * nextstate, u_int * req_input,
		       sos_string * outbuf, sos_string * inbuf);
extern int test_state(char *user, char *acode, u_int * nextstate, u_int * req_input,
		      sos_string * outbuf, sos_string * inbuf);
extern void test_cleanup(char *user, char *acode);

#endif				/*TEST_AUTH */
#ifdef UNIX_AUTH
extern int unix_challenge(char *user, char *acode, u_int * nextstate, u_int * req_input,
			  sos_string * outbuf, sos_string * inbuf);
extern int unix_auth(char *user, char *acode, u_int * nextstate, u_int * req_input,
		     sos_string * outbuf, sos_string * inbuf);
extern int unix_passwd(char *user, char *acode, u_int * nextstate, u_int * req_input,
		       sos_string * outbuf, sos_string * inbuf);
extern int unix_state(char *user, char *acode, u_int * nextstate, u_int * req_input,
		      sos_string * outbuf, sos_string * inbuf);
extern void unix_cleanup(char *user, char *acode);

#endif				/*UNIX_AUTH */
#ifdef HASH_STATIC_AUTH
extern int hash_static_challenge(char *user, char *acode, u_int * nextstate, u_int * req_input,
				 sos_string * outbuf, sos_string * inbuf);
extern int hash_static_auth(char *user, char *acode, u_int * nextstate, u_int * req_input,
			    sos_string * outbuf, sos_string * inbuf);
extern int hash_static_passwd(char *user, char *acode, u_int * nextstate, u_int * req_input,
			      sos_string * outbuf, sos_string * inbuf);
extern int hash_static_state(char *user, char *acode, u_int * nextstate, u_int * req_input,
			     sos_string * outbuf, sos_string * inbuf);
extern void hash_static_cleanup(char *user, char *acode);

#endif				/*HASH_STATIC_AUTH */

#ifdef HASH_DYNAMIC_AUTH
extern int hash_dynamic_challenge(char *user, char *acode, u_int * nextstate, u_int * req_input,
				  sos_string * outbuf, sos_string * inbuf);
extern int hash_dynamic_auth(char *user, char *acode, u_int * nextstate, u_int * req_input,
			     sos_string * outbuf, sos_string * inbuf);
extern int hash_dynamic_passwd(char *user, char *acode, u_int * nextstate, u_int * req_input,
			       sos_string * outbuf, sos_string * inbuf);
extern int hash_dynamic_state(char *user, char *acode, u_int * nextstate, u_int * req_input,
			      sos_string * outbuf, sos_string * inbuf);
extern void hash_dynamic_cleanup(char *user, char *acode);

#endif				/*HASH_DYNAMIC_AUTH */

#ifdef SKEY_AUTH
extern int skey_challenge(char *user, char *acode, u_int * nextstate, u_int * req_input,
			  sos_string * outbuf, sos_string * inbuf);
extern int skey_auth(char *user, char *acode, u_int * nextstate, u_int * req_input,
		     sos_string * outbuf, sos_string * inbuf);
extern int skey_passwd(char *user, char *acode, u_int * nextstate, u_int * req_input,
		       sos_string * outbuf, sos_string * inbuf);
extern int skey_state(char *user, char *acode, u_int * nextstate, u_int * req_input,
		      sos_string * outbuf, sos_string * inbuf);
extern void skey_cleanup(char *user, char *acode);

#endif				/*SKEY_AUTH */
#ifdef ENIGMA_AUTH
extern int enig_challenge(char *user, char *acode, u_int * nextstate, u_int * req_input,
			  sos_string * outbuf, sos_string * inbuf);
extern int enig_auth(char *user, char *acode, u_int * nextstate, u_int * req_input,
		     sos_string * outbuf, sos_string * inbuf);
extern int enig_passwd(char *user, char *acode, u_int * nextstate, u_int * req_input,
		       sos_string * outbuf, sos_string * inbuf);
extern int enig_state(char *user, char *acode, u_int * nextstate, u_int * req_input,
		      sos_string * outbuf, sos_string * inbuf);
extern void enig_cleanup(char *user, char *acode);

#endif				/*ENIGMA_AUTH */
#ifdef SECURID_AUTH
extern int sid_challenge(char *user, char *acode, u_int * nextstate, u_int * req_input,
			 sos_string * outbuf, sos_string * inbuf);
extern int sid_auth(char *user, char *acode, u_int * nextstate, u_int * req_input,
		    sos_string * outbuf, sos_string * inbuf);
extern int sid_passwd(char *user, char *acode, u_int * nextstate, u_int * req_input,
		      sos_string * outbuf, sos_string * inbuf);
extern int sid_state(char *user, char *acode, u_int * nextstate, u_int * req_input,
		     sos_string * outbuf, sos_string * inbuf);
extern void sid_cleanup(char *user, char *acode);

#endif				/*SECURID_AUTH */
#ifdef CCARD_AUTH
extern int ccard_challenge(char *user, char *acode, u_int * nextstate, u_int * req_input,
			   sos_string * outbuf, sos_string * inbuf);
extern int ccard_auth(char *user, char *acode, u_int * nextstate, u_int * req_input,
		      sos_string * outbuf, sos_string * inbuf);
extern int ccard_passwd(char *user, char *acode, u_int * nextstate, u_int * req_input,
			sos_string * outbuf, sos_string * inbuf);
extern int ccard_state(char *user, char *acode, u_int * nextstate, u_int * req_input,
		       sos_string * outbuf, sos_string * inbuf);
extern void ccard_cleanup(char *user, char *acode);

#endif				/*CCARD_AUTH */

/* internal recursive routines */
extern int CheckGroup(char *, struct timeinfo_t, int, struct in_addr, unsigned short, struct in_addr, unsigned short);
extern int CheckTime(char *metaname, struct timeinfo_t time);
extern int CheckDate(char *metaname, int date);
extern int CheckAddr(char *metaname, struct in_addr addr);
extern int CheckServ(char *metaname, unsigned short serv);

/* misc stuff */
extern int copyout(char *);
extern int orderdll(dict_h dll, dict_obj from, dict_obj to);
extern int days2bit(int a, int b);
extern int hour2bit(int a, int b);
extern int initFiles(char *name);
extern void FreeIncludeFiles();
extern void InitIncludeFiles();
extern int AddFiles(char *name);

extern FILE *yyin;

#endif				/*!_bs_readconf_h */
