// -*-c++-*-
/* $Id: authdb.h,v 1.18 2002/10/25 21:44:50 max Exp $ */

/*
 *
 * Copyright (C) 2001 David Mazieres (dm@uun.org)
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 */

#ifndef _SFSAUTHD_AUTHDB_H_
#define _SFSAUTHD_AUTHDB_H_ 1

#include "sfscrypt.h"
#include "amisc.h"
#include "authdb_types.h"
#include "qhash.h"

struct authdb;

struct authcursor {
  sfsauth_dbrec ae;
  ptr<sfspub> pubkey;

  authcursor () {}
  virtual ~authcursor () {}
  virtual void reset () = 0;
  virtual bool next (bool *pep = NULL) = 0;
  virtual bool validate () ;
  // virtual bool first () = { reset (); return next (); }
  virtual bool update (bool create = false) { return false; }
  virtual bool commit () { return true; }

  virtual bool find_user_name (str name);
  virtual bool find_user_pubkey (const sfspub &pk);
  virtual bool find_user_uid (u_int32_t uid);

  virtual bool find_group_name (str name);
  virtual bool find_group_gid (u_int32_t gid);

  virtual void getgroups (vec<u_int32_t> *groups, str user);
};

class authcursor_file_append : public authcursor {
  const ref<lockfile> lf;
  const str path;
  int wfd;
  suio buf;
  bhash<str> keys;

protected:
  authcursor_file_append (const ref<lockfile> l, str p, int wfd)
    : lf (l), path (p), wfd (wfd) { assert (wfd >= 0); }
  ~authcursor_file_append ();

public:
  void reset () { close (wfd); wfd = -1; }
  bool next (bool *pep = NULL) { return false; }
  bool update (bool create = false);
  bool commit ();
  static ptr<authcursor_file_append> alloc (str path, mode_t perm,
					    ref<lockfile> lf);
};

struct authdb {
  virtual ~authdb () {}
  virtual ptr<authcursor> trunc (bool wait = false) { return NULL; }
  virtual ptr<authcursor> open (bool writable = false, mode_t perm = 0600,
				bool wait = false) = 0;
};

struct authdb_etc_group : public authdb {
  ptr<authcursor> open (bool writable, mode_t perm = 0600, bool wait = false);
};

class authdb_file : public authdb {
  bool locked;
  str path;
public:
  authdb_file (str path) : locked (false), path (path) {}
  ptr<authcursor> open (bool writable, mode_t perm, bool wait = false);
  ptr<authcursor> trunc (mode_t perm, bool wait = false);
};

class authdb_dir : public authdb {
  ptr<lockfile> lf;

  str dirpath;
  str cachepath;
  u_int32_t uidstart;
  u_int32_t uidend;
  u_int32_t gid;
  int depth;

public:
  authdb_dir (ptr<lockfile> lf, str dirpath, str cachepath, 
	      u_int32_t uidstart, u_int32_t uidend, u_int32_t gid, int depth) :
    lf (lf), dirpath (dirpath), cachepath (cachepath),
    uidstart (uidstart), uidend (uidend), gid (gid), depth (depth) {}
  ptr<authcursor> open (bool writable, mode_t perm, bool wait = false);
};

str authdbrec2str (const sfsauth_dbrec *dbr);
bool str2authdbrec (sfsauth_dbrec *dbr, str s);
str single_char_sub (const str &in, const char find, const str &repl);

#endif /* !_SFSAUTHD_AUTHDB_H_ */
