/* -*-c-*-
*
- * $Id: acconfig.h,v 1.1 1997/08/04 10:22:09 mdw Exp $
+ * $Id: acconfig.h,v 1.2 1997/08/04 10:24:19 mdw Exp $
*
* Default settings for `become' config.h
*
/*----- Revision history --------------------------------------------------*
*
* $Log: acconfig.h,v $
- * Revision 1.1 1997/08/04 10:22:09 mdw
+ * Revision 1.2 1997/08/04 10:24:19 mdw
* Sources placed under CVS control.
*
* Revision 1.1 1997/07/21 13:47:52 mdw
dnl -*-fundamental-*-
dnl
-dnl $Id: aclocal.m4,v 1.1 1997/08/04 10:22:10 mdw Exp $
+dnl $Id: aclocal.m4,v 1.2 1997/08/04 10:24:19 mdw Exp $
dnl
dnl Configuration macros for `become'
dnl
dnl----- Revision history ---------------------------------------------------
dnl
dnl $Log: aclocal.m4,v $
-dnl Revision 1.1 1997/08/04 10:22:10 mdw
+dnl Revision 1.2 1997/08/04 10:24:19 mdw
dnl Sources placed under CVS control.
dnl
dnl -*-fundamental-*-
dnl
-dnl $Id: configure.in,v 1.1 1997/07/21 13:47:51 mdw Exp $
+dnl $Id: configure.in,v 1.2 1997/08/04 10:24:21 mdw Exp $
dnl
dnl Source for auto configuration for `become'
dnl
dnl (c) 1997 Mark Wooding
dnl
-dnl----- Licencing notice ---------------------------------------------------
+dnl----- Licensing notice ---------------------------------------------------
dnl
dnl This file is part of `become'
dnl
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
-dnl along with `become'; if not, write to the Free Software
-dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+dnl along with `become'; if not, write to the Free Software Foundation,
+dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
dnl----- Revision history ---------------------------------------------------
dnl
dnl $Log: configure.in,v $
-dnl Revision 1.1 1997/07/21 13:47:51 mdw
-dnl Initial revision
+dnl Revision 1.2 1997/08/04 10:24:21 mdw
+dnl Sources placed under CVS control.
dnl
+# Revision 1.1 1997/07/21 13:47:51 mdw
+# Initial revision
+#
AC_INIT(icrypt.c)
AC_CONFIG_HEADER(config.h)
-VERSION=1.1 AC_SUBST(VERSION)
-AC_DEFINE(VERSION, "1.1 (22 February 1997)")
+PACKAGE=become VERSION=1.2-pre
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+AC_DEFINE(VERSION, "1.2-pre (24 July 1997)")
dnl --- Check for compilers and things ---
AC_CHECK_PROG(AR, ar, ar)
AC_PROG_RANLIB
AC_PROG_YACC
+AC_ARG_PROGRAM
if test "$ac_cv_prog_gcc" = "yes"; then
CFLAGS="$CFLAGS -pedantic -Wall"
fi
dnl --- Libraries ---
-AC_CHECK_LIB(socket, socket)
-MDW_LIB_RESOLVER
+MDW_CHECK_MANYLIBS(socket, socket,,
+ AC_MSG_ERROR([Socket library not found]))
+
+MDW_CHECK_MANYLIBS(gethostbyname, resolv nsl,,
+ AC_MSG_ERROR([Resolver library not found]))
+
+MDW_CHECK_MANYLIBS(yp_all, nsl, AC_DEFINE(HAVE_YP))
dnl --- Types ---
AC_TYPE_PID_T
AC_TYPE_UID_T
-
-dnl --- Check on endianness ---
-
-AC_C_BIGENDIAN(yes)
+AC_CHECK_TYPE(ssize_t, int)
dnl --- Check on type sizes ---
-AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(int, 2)
dnl --- Set the path separator ---
AC_DEFINE(PATHSEP, '/')
+dnl --- Check for some useful functions ---
+
+AC_CHECK_FUNCS(getrusage vtimes)
+
dnl --- Debugging stuff ---
AC_ARG_ENABLE(debugging,
- [--enable-debugging spews vast swathes of useless information],
+[ --enable-debugging spews vast swathes of useless information],
[if test "$enableval" = "no"; then
AC_DEFINE(NDEBUG, 1)
fi],
AC_DEFINE(NDEBUG, 1))
-dnl --- Yell^H^H^H^HNetwork Information System ---
-
-AC_ARG_ENABLE(yp,
- [--enable-yp read user names using ypcat],
- [if test "$enableval" != "no"; then
- AC_DEFINE(HAVE_YP, 1)
+AC_ARG_ENABLE(tracing,
+[ --enable-tracing enable output of tracing information],
+ [if test "$enableval" = "yes"; then
+ AC_DEFINE(TRACING)
fi],
- MDW_CHECK_YP)
+ AC_DEFINE(TRACING))
dnl --- Define where things get put ---
mdw_save_prefix="$prefix"
-test "x$prefix" = "xNONE" && prefix="$ac_default_prefix"
+test "$prefix" = "NONE" && prefix="$ac_default_prefix"
AC_DEFINE_UNQUOTED(ETCDIR, "`eval echo ${sysconfdir}`")
prefix="$mdw_save_prefix"
%%% -*-LaTeX-*-
%%%
-%%% $Id: become.tex,v 1.1 1997/07/21 13:47:54 mdw Exp $
+%%% $Id: become.tex,v 1.2 1997/08/04 10:24:20 mdw Exp $
%%%
%%% Documentation for `become'
%%%
%%%----- Revision history ---------------------------------------------------
%%%
%%% $Log: become.tex,v $
-%%% Revision 1.1 1997/07/21 13:47:54 mdw
-%%% Initial revision
+%%% Revision 1.2 1997/08/04 10:24:20 mdw
+%%% Sources placed under CVS control.
%%%
+% Revision 1.1 1997/07/21 13:47:54 mdw
+% Initial revision
+%
%%%----- Document preamble --------------------------------------------------
# Created: 1993-05-16
# Public domain
-# $Id: mkinstalldirs,v 1.1 1997/08/04 10:22:10 mdw Exp $
+# $Id: mkinstalldirs,v 1.2 1997/08/04 10:24:24 mdw Exp $
errstatus=0
## Process this file with `automake' to generate `Makefile.in'
## -*-makefile-*-
##
-## $Id: Makefile.am,v 1.1 1997/08/04 10:22:09 mdw Exp $
+## $Id: Makefile.am,v 1.2 1997/08/04 10:24:19 mdw Exp $
##
## Makefile for `become'
##
##----- Revision history ----------------------------------------------------
##
## $Log: Makefile.am,v $
-## Revision 1.1 1997/08/04 10:22:09 mdw
+## Revision 1.2 1997/08/04 10:24:19 mdw
## Sources placed under CVS control.
##
/* -*-c-*-
*
- * $Id: become.c,v 1.1 1997/07/21 13:47:54 mdw Exp $
+ * $Id: become.c,v 1.2 1997/08/04 10:24:20 mdw Exp $
*
* Main code for `become'
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: become.c,v $
- * Revision 1.1 1997/07/21 13:47:54 mdw
+ * Revision 1.2 1997/08/04 10:24:20 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:54 mdw
* Initial revision
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
/* --- Unix headers --- */
#include <syslog.h>
#include <unistd.h>
+extern char **environ;
+
/* --- Local headers --- */
#include "become.h"
#include "parser.h"
#include "rule.h"
#include "utils.h"
+#include "userdb.h"
/*----- Main code ---------------------------------------------------------*/
" $ -d [-p <port>] [-f <config-file>]\n");
}
+/* --- @bc__makeEnv@ --- *
+ *
+ * Arguments: @const char *var@ = name of an environment variable
+ * @const char *value@ = value of the variable
+ *
+ * Returns: A pointer to an allocated block assigning the value to the
+ * name.
+ *
+ * Use: Constructs environment mappings.
+ */
+
+static char *bc__makeEnv(const char *var, const char *value)
+{
+ char *p = xmalloc(strlen(var) + strlen(value) + 2);
+ sprintf(p, "%s=%s", var, value);
+ return (p);
+}
+
/* --- @bc__help@ --- *
*
* Arguments: @FILE *fp@ = stream to write on
"\n"
"-h, --help Display this help text\n"
"-v, --version Display the version number of this copy of $\n"
+"-l, --login Really log in as the user\n"
"-c, --command=CMD Run the (Bourne) shell command CMD\n"
"-d, --daemon Start up a daemon, to accept requests from clients\n"
"-p, --port=PORT In daemon mode, listen on PORT\n"
"-f, --config-file=FILE In daemon mode, read config from FILE\n"
-"--yacc-debug Dump lots of parser diagnostics (boring)\n");
+#ifdef TRACING
+"--impersonate=USER Claim to be USER when asking the server\n"
+"--trace=FILE Dump trace information to FILE (boring)\n"
+"--trace-level=OPTS Set level of tracing information\n"
+#endif
+);
}
/* --- @main@ --- *
int main(int argc, char *argv[])
{
- char *cmd = 0;
- static char *shell[] = { "/bin/sh", "-c", 0, 0 };
- char **todo;
- request rq;
- char buff[CMDLEN_MAX];
- char *conffile = file_RULES;
- int port = -1;
+ /* --- Request block setup parameters --- */
- enum {
- f_daemon = 1,
- f_duff = 2
+ request rq; /* Request buffer to build */
+ char *cmd = 0; /* Shell command to execute */
+ char *binary = "/bin/sh"; /* Default binary to execute */
+ char **env = environ; /* Default environment to pass */
+ char **todo; /* Pointer to argument list */
+ struct passwd *from_pw = 0; /* User we are right now */
+ struct passwd *to_pw = 0; /* User we want to become */
+
+ /* --- Become server setup parameters --- */
+
+ char *conffile = file_RULES; /* Default config file for daemon */
+ int port = -1; /* Default port for daemon */
+
+ /* --- Miscellanous shared variables --- */
+
+ unsigned flags = 0; /* Various useful flags */
+
+ /* --- Default argument list executes a shell command --- */
+
+ static char *shell[] = {
+ "/bin/sh", /* Bourne shell */
+ "-c", /* Read from command line */
+ 0, /* Pointer to shell command */
+ 0 /* Terminator */
};
- unsigned flags = 0;
+ /* --- Login request replaces the environment with this --- */
+
+ static char *mangled_env[] = {
+ "PATH=/bin:/usr/bin", /* Default `clean' path*/
+ 0, /* User's name (`USER') */
+ 0, /* User's name (`LOGNAME') */
+ 0, /* Home directory (`HOME') */
+ 0 /* Terminator */
+ };
+
+ /* --- Definitions for the various flags --- */
+
+ enum {
+ f_daemon = 1, /* Start up in daemon mode */
+ f_duff = 2, /* Fault in arguments */
+ f_login = 4, /* Execute as a login shell */
+ f_dummy = 8, /* Don't actually do anything */
+ f_setuid = 16 /* We're running setuid */
+ };
/* --- Set up the program name --- */
ego(argv[0]);
+ clock();
+ if (getuid() != geteuid())
+ flags |= f_setuid;
/* --- Parse some command line arguments --- */
for (;;) {
int i;
- struct option opts[] = {
+ static struct option opts[] = {
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
+ { "login", 0, 0, 'l' },
{ "command", gFlag_argReq, 0, 'c' },
{ "daemon", 0, 0, 'd' },
{ "port", gFlag_argReq, 0, 'p' },
{ "config-file", gFlag_argReq, 0, 'f' },
- { "yacc-debug", 0, 0, 'Y' },
+#ifdef TRACING
+ { "impersonate", gFlag_argReq, 0, 'I' },
+ { "trace", gFlag_argOpt, 0, 'T' },
+ { "trace-level", gFlag_argOpt, 0, 'L' },
+#endif
{ 0, 0, 0, 0 }
};
- i = mdwopt(argc, argv, "hvc:p:df:", opts, 0, 0, 0);
+ i = mdwopt(argc, argv, "+hvlc:p:df:", opts, 0, 0, 0);
if (i < 0)
break;
switch (i) {
+
+ /* --- Standard help and version options --- */
+
case 'h':
bc__help(stdout);
exit(0);
bc__banner(stdout);
exit(0);
break;
+
+ /* --- Various simple options --- */
+
+ case 'l':
+ flags |= f_login;
+ break;
case 'c':
cmd = optarg;
break;
case 'f':
conffile = optarg;
break;
- case 'Y':
- if (getuid() == geteuid())
- yydebug = 1;
- else
- moan("won't set debugging mode when running setuid");
+
+ /* --- Pretend to be a different user --- *
+ *
+ * There are all sorts of nasty implications for this option. Don't
+ * allow it if we're running setuid. Disable the actual login anyway.
+ */
+
+#ifdef TRACING
+ case 'I':
+ if (flags & f_setuid)
+ moan("shan't allow impersonation while running setuid");
+ else {
+ struct passwd *pw;
+ if (isdigit((unsigned char)optarg[0]))
+ pw = getpwuid(atoi(optarg));
+ else
+ pw = getpwnam(optarg);
+ if (!pw)
+ die("can't impersonate unknown user `%s'", optarg);
+ from_pw = userdb_copyUser(pw);
+ rq.from = from_pw->pw_uid;
+ flags |= f_dummy;
+ }
break;
+#endif
+
+ /* --- Tracing support --- *
+ *
+ * Be careful not to zap a file I wouldn't normally be allowed to write
+ * to!
+ */
+
+#ifdef TRACING
+
+ case 'T': {
+ FILE *fp;
+
+ if (optarg == 0 || strcmp(optarg, "-") == 0)
+ fp = stdout;
+ else {
+ if ((flags & f_setuid) && access(optarg, W_OK)) {
+ die("no write permission for trace file file `%s': %s",
+ optarg, strerror(errno));
+ }
+ if ((fp = fopen(optarg, "w")) == 0) {
+ die("couldn't open trace file `%s' for writing: %s",
+ optarg, strerror(errno));
+ }
+ }
+ traceon(fp, TRACE_DFL);
+ trace(TRACE_MISC, "become: tracing enabled");
+ } break;
+
+#endif
+
+ /* --- Setting trace levels --- */
+
+#ifdef TRACING
+
+ case 'L': {
+ int sense = 1;
+ unsigned int lvl = 0, l;
+ const char *p = optarg;
+
+ /* --- Table of tracing facilities --- */
+
+ typedef struct tr {
+ char ch;
+ unsigned int l;
+ const char *help;
+ } tr;
+
+ static tr lvltbl[] = {
+ { 'm', TRACE_MISC, "miscellaneous messages" },
+ { 's', TRACE_SETUP, "building the request block" },
+ { 'd', TRACE_DAEMON, "server process" },
+ { 'r', TRACE_RULE, "ruleset scanning" },
+ { 'c', TRACE_CHECK, "request checking" },
+ { 'l', TRACE_CLIENT, "client process" },
+ { 'R', TRACE_RAND, "random number generator" },
+ { 'C', TRACE_CRYPTO, "cryptographic processing of requests" },
+ { 'y', TRACE_YACC, "parsing configuration file" },
+ { 'D', TRACE_DFL, "default tracing options" },
+ { 'A', TRACE_ALL, "all tracing options" },
+ { 0, 0, 0 }
+ };
+ tr *tp;
+
+ /* --- Output some help if there's no arguemnt --- */
+
+ if (!optarg) {
+ bc__banner(stdout);
+ bc__write(stdout,
+ "\n"
+ "Tracing options:\n"
+ "\n");
+ for (tp = lvltbl; tp->l; tp++) {
+ if ((flags & f_setuid) == 0 || tp->l & ~TRACE_PRIV)
+ printf("%c -- %s\n", tp->ch, tp->help);
+ }
+ bc__write(stdout,
+"\n"
+"Also, `+' and `-' options are recognised to turn on and off vavrious\n"
+"tracing options. For example, `A-r' enables everything except ruleset\n"
+"tracing, and `A-D+c' is everything except the defaults, but with request\n"
+"check tracing.\n"
+);
+ exit(0);
+ }
+
+ while (*p) {
+ if (*p == '+')
+ sense = 1;
+ else if (*p == '-')
+ sense = 0;
+ else {
+ for (tp = lvltbl; tp->l && *p != tp->ch; tp++)
+ ;
+ l = tp->l;
+ if (flags & f_setuid)
+ l &= ~TRACE_PRIV;
+ if (l)
+ lvl = sense ? (lvl | l) : (lvl & ~l);
+ else
+ moan("unknown trace option `%c'", *p);
+ }
+ p++;
+ }
+
+ tracesetlvl(lvl);
+ yydebug = ((lvl & TRACE_YACC) != 0);
+ } break;
+
+#endif
+
+ /* --- Something I didn't understand has occurred --- */
+
case '?':
flags |= f_duff;
break;
/* --- Switch to daemon mode if requested --- */
if (flags & f_daemon) {
+ T( trace(TRACE_MISC, "become: daemon mode requested"); )
daemon_init(conffile, port);
exit(0);
}
{
const char *u;
struct passwd *pw;
+
if (optind >= argc) {
bc__usage(stderr);
exit(1);
}
u = argv[optind++];
- pw = getpwnam(u);
- if (!pw && isdigit(u[0]))
+
+ if (isdigit((unsigned char)u[0]))
pw = getpwuid(atoi(u));
+ else
+ pw = getpwnam(u);
if (!pw)
die("unknown user `%s'", u);
+ to_pw = userdb_copyUser(pw);
rq.to = pw->pw_uid;
}
/* --- Fill in the easy bits of the request --- */
- rq.from = getuid();
+ if (!from_pw) {
+ struct passwd *pw;
+
+ rq.from = getuid();
+ pw = getpwuid(rq.from);
+ if (!pw)
+ die("who are you? (can't find user %li)", (long)rq.from);
+ from_pw = userdb_copyUser(pw);
+ }
/* --- Find the local host address --- */
memcpy(&rq.host, he->h_addr, sizeof(struct in_addr));
}
- /* --- Figure out what command to use --- */
+ /* --- Shell commands are easy --- */
if (cmd) {
shell[2] = cmd;
todo = shell;
- } else if (optind < argc) {
+ }
+
+ /* --- A command given on the command line isn't too hard --- */
+
+ else if (optind < argc) {
todo = argv + optind;
- } else {
- struct passwd *pw = getpwuid(rq.from);
- if (!pw)
- die("who are you? (can't find uid %li in database)", (long)rq.from);
- shell[0] = pw->pw_shell;
+ binary = todo[0];
+ }
+
+ /* --- A login request needs a little bit of work --- */
+
+ else if (flags & f_login) {
+ const char *p = strrchr(to_pw->pw_shell, '/');
+ if (p)
+ p++;
+ else
+ p = to_pw->pw_shell;
+ shell[0] = xmalloc(strlen(p) + 2);
+ shell[0][0] = '-';
+ strcpy(shell[0] + 1, p);
shell[1] = 0;
todo = shell;
+ binary = to_pw->pw_shell;
}
+ /* --- An unadorned becoming requires little work --- */
+
+ else {
+ shell[0] = from_pw->pw_shell;
+ shell[1] = 0;
+ todo = shell;
+ binary = todo[0];
+ }
+
+ /* --- Mangle the environment if login flag given --- */
+
+ if (flags & f_login) {
+ env = mangled_env;
+ env[1] = bc__makeEnv("USER", to_pw->pw_name);
+ env[2] = bc__makeEnv("LOGNAME", to_pw->pw_name);
+ env[3] = bc__makeEnv("HOME", to_pw->pw_dir);
+ }
+
+ /* --- Trace the command --- */
+
+ IF_TRACING(TRACE_SETUP, {
+ int i;
+
+ trace(TRACE_SETUP, "setup: from user %s to user %s",
+ from_pw->pw_name, to_pw->pw_name);
+ trace(TRACE_SETUP, "setup: binary == `%s'", binary);
+ for (i = 0; todo[i]; i++)
+ trace(TRACE_SETUP, "setup: arg %i == `%s'", i, todo[i]);
+ for (i = 0; env[i]; i++)
+ trace(TRACE_SETUP, "setup: env %i == `%s'", i, env[i]);
+ })
+
/* --- If necessary, resolve the path to the command --- */
- if (!strchr(todo[0], '/')) {
- char *path;
- char *p;
+ if (!strchr(binary, '/')) {
+ char *path, *p;
struct stat st;
- size_t sz;
if ((p = getenv("PATH")) == 0)
p = "/bin:/usr/bin";
- sz = strlen(p) + 1;
- memcpy(path = xmalloc(sz), p, sz);
+ path = xstrdup(p);
for (p = strtok(path, ":"); (p = strtok(0, ":")) != 0; ) {
/* --- SECURITY: check length of string before copying --- */
- if (strlen(p) + strlen(todo[0]) + 2 > sizeof(buff))
+ if (strlen(p) + strlen(binary) + 2 > sizeof(rq.cmd))
continue;
/* --- Now build the pathname and check it --- */
- sprintf(buff, "%s/%s", p, todo[0]);
- if (stat(buff, &st) == 0 && /* Check it exists */
+ sprintf(rq.cmd, "%s/%s", p, todo[0]);
+ if (stat(rq.cmd, &st) == 0 && /* Check it exists */
st.st_mode & 0111 && /* Check it's executable */
(st.st_mode & S_IFMT) == S_IFREG) /* Check it's a file */
break;
if (!p)
die("couldn't find `%s' in path", todo[0]);
- todo[0] = buff;
+ binary = rq.cmd;
free(path);
}
+ T( trace(TRACE_SETUP, "setup: resolve binary to `%s'", binary); )
/* --- Canonicalise the path string, if necessary --- */
/* --- Insert current directory name if path not absolute --- */
p = b;
- q = todo[0];
+ q = binary;
if (*q != '/') {
if (!getcwd(b, sizeof(b)))
die("couldn't read current directory: %s", strerror(errno));
*/
if (p >= b + sizeof(b) - 1)
- die("buffer overflow -- bad things happened");
+ die("internal error: buffer overflow while canonifying path");
/* --- Reduce multiple slashes to just one --- */
*p++ = 0;
strcpy(rq.cmd, b);
}
+ T( trace(TRACE_SETUP, "setup: canonify binary to `%s'", rq.cmd); )
/* --- Run the check --- */
{
int a = check(&rq);
- char from[16], to[16];
- struct passwd *pw;
-
- if ((pw = getpwuid(rq.from)) != 0)
- sprintf(from, "%.15s", pw->pw_name);
- else
- sprintf(from, "user %lu", (unsigned long)rq.from);
-
- if ((pw = getpwuid(rq.to)) != 0)
- sprintf(to, "%.15s", pw->pw_name);
- else
- sprintf(to, "user %lu", (unsigned long)rq.to);
syslog(LOG_INFO,
"permission %s for %s to become %s to run `%s'",
- a ? "granted" : "denied", from, to, rq.cmd);
+ a ? "granted" : "denied", from_pw->pw_name, to_pw->pw_name,
+ rq.cmd);
if (!a)
die("permission denied");
/* --- Now do the job --- */
-#ifdef TEST_RIG
- printf("ok\n");
- return (0);
-#else
- if (setuid(rq.to) == -1 || seteuid(rq.to) == -1)
- die("couldn't set uid: %s", strerror(errno));
- execv(rq.cmd, todo);
- die("couldn't exec `%s': %s", rq.cmd, strerror(errno));
- return (127);
-#endif
+ T( trace(TRACE_MISC, "become: permission granted"); )
+
+ if (flags & f_dummy) {
+ puts("permission granted");
+ return (0);
+ } else {
+ if (setuid(rq.to) == -1 || seteuid(rq.to) == -1)
+ die("couldn't set uid: %s", strerror(errno));
+ execve(rq.cmd, todo, env);
+ die("couldn't exec `%s': %s", rq.cmd, strerror(errno));
+ return (127);
+ }
}
/*----- That's all, folks -------------------------------------------------*/
/* -*-c-*-
*
- * $Id: blowfish-sbox.h,v 1.1 1997/07/21 13:47:54 mdw Exp $
+ * $Id: blowfish-sbox.h,v 1.2 1997/08/04 10:24:20 mdw Exp $
*
* Blowfish encryption routines
*
/*----- Revision history --------------------------------------------------*
*
* $Log: blowfish-sbox.h,v $
- * Revision 1.1 1997/07/21 13:47:54 mdw
+ * Revision 1.2 1997/08/04 10:24:20 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:54 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: blowfish.c,v 1.1 1997/07/21 13:47:53 mdw Exp $
+ * $Id: blowfish.c,v 1.2 1997/08/04 10:24:20 mdw Exp $
*
* Blowfish encryption routines
*
/*----- Revision history --------------------------------------------------*
*
* $Log: blowfish.c,v $
- * Revision 1.1 1997/07/21 13:47:53 mdw
+ * Revision 1.2 1997/08/04 10:24:20 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:53 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: blowfish.h,v 1.1 1997/07/21 13:47:53 mdw Exp $
+ * $Id: blowfish.h,v 1.2 1997/08/04 10:24:20 mdw Exp $
*
* Blowfish encryption routines
*
/*----- Revision history --------------------------------------------------*
*
* $Log: blowfish.h,v $
- * Revision 1.1 1997/07/21 13:47:53 mdw
+ * Revision 1.2 1997/08/04 10:24:20 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:53 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: check.c,v 1.1 1997/07/21 13:47:53 mdw Exp $
+ * $Id: check.c,v 1.2 1997/08/04 10:24:20 mdw Exp $
*
* Check validity of requests
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: check.c,v $
- * Revision 1.1 1997/07/21 13:47:53 mdw
+ * Revision 1.2 1997/08/04 10:24:20 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:53 mdw
* Initial revision
*
*/
#include "rule.h"
#include "parser.h"
#include "tx.h"
+#include "userdb.h"
#include "utils.h"
/*----- Main code ---------------------------------------------------------*/
-/* --- @check__client@ --- *
+/* --- @check__send@ --- *
+ *
+ * Arguments: @unsigned char *crq@ = pointer to encrypted request
+ * @int fd@ = socket to send from
+ * @struct sockaddr_in *serv@ = pointer to table of servers
+ * @size_t n_serv@ = number of servers
+ *
+ * Returns: ---
+ *
+ * Use: Sends the request packet to the list of servers. If the
+ * message couldn't be sent to any of them, an error is
+ * reported.
+ */
+
+static void check__send(unsigned char *crq, int fd,
+ struct sockaddr_in *serv, size_t n_serv)
+{
+ size_t i;
+ int ok = 0;
+ int err = 0;
+
+ for (i = 0; i < n_serv; i++) {
+ if (sendto(fd, (char *)crq, crq_size, 0,
+ (struct sockaddr *)(serv + i), sizeof(serv[i])) < 0) {
+ T( trace(TRACE_CLIENT, "client: send to %s failed: %s",
+ inet_ntoa(serv[i].sin_addr), strerror(errno)); )
+ err = errno;
+ } else
+ ok = 1;
+ }
+
+ if (!ok)
+ die("couldn't send request to server: %s", strerror(err));
+}
+
+/* --- @check__ask@ --- *
*
* Arguments: @request *rq@ = pointer to request buffer
- * @const char *serv@ = pointer to the server
- * @int port@ = port number to use
+ * @struct sockaddr_in *serv@ = pointer to table of servers
+ * @size_t n_serv@ = number of servers
*
* Returns: Nonzero if OK, zero if forbidden
*
- * Use: Contacts a server to decide whether the request is OK.
+ * Use: Contacts a number of servers to decide whether the request
+ * is OK.
*/
-static int check__client(request *rq, const char *serv, int port)
+static int check__ask(request *rq, struct sockaddr_in *serv, size_t n_serv)
{
int fd;
- struct sockaddr_in ssin;
unsigned char crq[crq_size];
- unsigned char k[IDEA_KEYSIZE];
unsigned char sk[IDEA_KEYSIZE];
time_t t;
pid_t pid;
- /* --- Create my socket --- */
+ /* --- First, build the encrypted request packet --- */
- if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
- die("couldn't create socket: %s", strerror(errno));
+ {
+ unsigned char k[IDEA_KEYSIZE];
+ FILE *fp;
- /* --- Bind myself to some address --- */
+ /* --- Read in the encryption key --- */
- {
- struct sockaddr_in sin;
+ if ((fp = fopen(file_KEY, "r")) == 0) {
+ die("couldn't open key file `%s': %s", file_KEY,
+ strerror(errno));
+ }
+ tx_getBits(k, 128, fp);
- sin.sin_family = AF_INET;
- sin.sin_port = 0;
- sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ /* --- Now build a request packet --- */
- if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- die("couldn't bind socket to address: %s", strerror(errno));
+ t = time(0);
+ pid = getpid();
+ crypt_packRequest(rq, crq, t, pid, k, sk);
+ burn(k);
+ T( trace(TRACE_CLIENT, "client: encrypted request packet"); )
}
- /* --- Find the server's address --- */
+ /* --- Create my socket --- */
{
- struct hostent *he;
+ struct sockaddr_in sin;
- /* --- Resolve the server's name --- */
+ if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
+ die("couldn't create socket: %s", strerror(errno));
- if ((he = gethostbyname(serv)) == 0)
- die("couldn't find server host `%s'", serv);
+ /* --- Bind myself to some address --- */
- /* --- Build the address block --- */
+ sin.sin_family = AF_INET;
+ sin.sin_port = 0;
+ sin.sin_addr.s_addr = htonl(INADDR_ANY);
- ssin.sin_family = AF_INET;
- ssin.sin_port = htons(port);
- memcpy(&ssin.sin_addr, he->h_addr, sizeof(struct in_addr));
+ if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
+ die("couldn't bind socket to address: %s", strerror(errno));
}
- /* --- Read in the encryption key --- */
+ /* --- Now wait for a reply --- */
{
- FILE *fp;
-
- if ((fp = fopen(file_KEY, "r")) == 0) {
- die("couldn't open key file `%s': %s", file_KEY,
- strerror(errno));
- }
- tx_getBits(k, 128, fp);
- }
-
- /* --- Now build a request packet --- */
-
- t = time(0);
- pid = getpid();
- crypt_packRequest(rq, crq, t, pid, k, sk);
+ fd_set fds;
+ struct timeval start, now, tv;
+ int ind;
+ size_t i;
- /* --- Send the packet to the server --- */
+ /* --- State table for waiting for replies --- *
+ *
+ * For each number, send off the request to our servers, and wait for
+ * that many seconds to have elapsed since we started. If the number is
+ * %$-1$% then it's time to give up.
+ */
- if (sendto(fd, (char *)crq, sizeof(crq), 0,
- (struct sockaddr *)&ssin, sizeof(ssin)) < 0) {
- burn(k);
- die("couldn't send request to server: %s", strerror(errno));
- }
- burn(k);
+ static int tbl[] = { 0, 5, 10, 20, -1 };
- /* --- Now wait for a reply --- */
+ /* --- Find out when we are --- */
- {
- fd_set fds;
- struct timeval when, now, tv;
+ gettimeofday(&start, 0);
+ ind = 0;
- gettimeofday(&when, 0);
- when.tv_sec += 10;
+ /* --- Now loop until everything's done --- */
for (;;) {
- int i;
+ gettimeofday(&now, 0);
- /* --- Sort out when to return --- */
+ /* --- If the current timer has expired, find one that hasn't --- *
+ *
+ * Also resend the request after I've found a timer which is still
+ * extant. If there aren't any, report an error.
+ */
+
+ if (now.tv_sec >= start.tv_sec + tbl[ind] &&
+ now.tv_usec >= start.tv_usec) {
+ do {
+ ind++;
+ if (tbl[ind] < 0)
+ die("no reply from servers");
+ } while (now.tv_sec >= start.tv_sec + tbl[ind] &&
+ now.tv_usec >= start.tv_usec);
+ check__send(crq, fd, serv, n_serv);
+ T( trace(TRACE_CLIENT, "client: send request to servers"); )
+ }
- gettimeofday(&now, 0);
- if (now.tv_usec > when.tv_usec) {
+ /* --- Now wait for a packet to arrive --- */
+
+ if (now.tv_usec > start.tv_usec) {
now.tv_usec -= 1000000;
now.tv_sec += 1;
}
- tv.tv_sec = when.tv_sec - now.tv_sec;
- tv.tv_usec = when.tv_usec - now.tv_usec;
+ tv.tv_sec = start.tv_sec + tbl[ind] - now.tv_sec;
+ tv.tv_usec = start.tv_usec - now.tv_usec;
/* --- Sort out file descriptors to watch --- */
/* --- Wait for them --- */
i = select(FD_SETSIZE, &fds, 0, 0, &tv);
- if (i == 0)
- die("no answer from server");
+ if (i == 0 || (i < 0 && errno == EINTR))
+ continue;
if (i < 0)
die("error waiting for reply: %s", strerror(errno));
(struct sockaddr *)&sin, &slen) < 0)
die("error reading server's reply: %s", strerror(errno));
- /* --- Verify the sender --- */
-
- if (sin.sin_addr.s_addr != ssin.sin_addr.s_addr ||
- sin.sin_port != ssin.sin_port)
+ IF_TRACING(TRACE_CLIENT, {
+ struct hostent *h = gethostbyaddr((char *)&sin.sin_addr,
+ sizeof(sin.sin_addr), AF_INET);
+ trace(TRACE_CLIENT, "client: reply received from %s port %i",
+ h ? h->h_name : inet_ntoa(sin.sin_addr),
+ ntohs(sin.sin_port));
+ })
+
+ /* --- Verify the sender --- *
+ *
+ * This is more to avoid confusion than for security: an active
+ * attacker is quite capable of forging the source address. We rely
+ * on the checksum in the reply packet for authentication.
+ */
+
+ for (i = 0; i < n_serv; i++) {
+ if (sin.sin_addr.s_addr == serv[i].sin_addr.s_addr &&
+ sin.sin_port == serv[i].sin_port)
+ break;
+ }
+ if (i >= n_serv) {
+ T( trace(TRACE_CLIENT, "client: reply from unknown host"); )
continue;
+ }
/* --- Unpack and verify the response --- */
answer = crypt_unpackReply(buff, sk, t, pid);
- if (answer < 0)
+ if (answer < 0) {
+ T( trace(TRACE_CLIENT,
+ "client: invalid or corrupt reply packet"); )
continue;
+ }
return (answer);
}
}
}
- die("internal error: can't get here in check_client");
+ die("internal error: can't get here in check__ask");
return (0);
}
+/* --- @check__client@ --- *
+ *
+ * Arguments: @request *rq@ = pointer to a request block
+ * @FILE *fp@ = file containing server configuration
+ *
+ * Returns: Nonzero if OK, zero if forbidden
+ *
+ * Use: Asks one or several servers whether a request is acceptable.
+ */
+
+int check__client(request *rq, FILE *fp)
+{
+ /* --- Format of the file --- *
+ *
+ * The `servers' file contains entries of the form
+ *
+ * %%\syntax{<host> [`:' <port>]}%%
+ *
+ * separates by whitespace. I build them all into an array of socket
+ * addresses and pass the whole lot to another function.
+ */
+
+ struct sockaddr_in *serv; /* Array of servers */
+ size_t n_serv, max_serv; /* Number and maximum number */
+
+ /* --- Initialise the server array --- */
+
+ T( trace(TRACE_CLIENT, "client: reading server definitions"); )
+ n_serv = 0; max_serv = 4; /* Four seems reasonable */
+ serv = xmalloc(sizeof(*serv) * max_serv);
+
+ /* --- Start reading the file --- */
+
+ {
+ char buff[256], *p, *l; /* A buffer and pointers for it */
+ int port; /* Default port for servers */
+ int state; /* Current parser state */
+ struct in_addr t_host; /* Temp place for an address*/
+ int t_port; /* Temp place for a port */
+ int ch; /* The current character */
+
+ /* --- Parser states --- */
+
+ enum {
+ st_start, /* Waiting to begin */
+ st_host, /* Reading a new hostname */
+ st_colon, /* Expecting a colon, maybe */
+ st_preport, /* Waiting before reading port */
+ st_port, /* Reading a port number */
+ st_commit, /* Commit a newly read server */
+ st_done /* Finished reading the file */
+ };
+
+ /* --- Find a default port --- */
+
+ {
+ struct servent *s = getservbyname(quis(), "udp");
+ port = (s ? s->s_port : -1);
+ }
+
+ /* --- Initialise for scanning the file --- */
+
+ state = st_host;
+ p = buff;
+ l = buff + sizeof(buff);
+ t_port = port;
+ ch = getc(fp);
+
+ /* --- Go for it --- */
+
+ while (state != st_done) {
+ switch (state) {
+
+ /* --- Initial whitespace before hostname --- */
+
+ case st_start:
+ if (ch == EOF)
+ state = st_done;
+ else if (isspace((unsigned char)ch))
+ ch = getc(fp);
+ else
+ state = st_host;
+ break;
+
+ /* --- Read a host name --- */
+
+ case st_host:
+ if (p == l)
+ die("string too long in `" file_SERVER "'");
+ if (ch != EOF && !isspace((unsigned char)ch) && ch != ':') {
+ *p++ = ch;
+ ch = getc(fp);
+ } else {
+ struct hostent *h;
+
+ *p++ = 0;
+ if ((h = gethostbyname(buff)) == 0)
+ die("unknown host `%s' in `" file_SERVER "'", buff);
+ memcpy(&t_host, h->h_addr, sizeof(t_host));
+ state = st_colon;
+ }
+ break;
+
+ /* --- Waiting for a colon coming up --- */
+
+ case st_colon:
+ if (ch == EOF)
+ state = st_commit;
+ else if (isspace((unsigned char)ch))
+ ch = getc(fp);
+ else if (ch == ':') {
+ state = st_preport;
+ ch = getc(fp);
+ }
+ else
+ state = st_commit;
+ break;
+
+ /* --- Clearing whitespace before a port number --- */
+
+ case st_preport:
+ if (ch == EOF)
+ state = st_commit;
+ else if (isspace((unsigned char)ch))
+ ch = getc(fp);
+ else {
+ state = st_port;
+ p = buff;
+ }
+ break;
+
+ /* --- Read a port number --- */
+
+ case st_port:
+ if (p == l)
+ die("string too long in `" file_SERVER "'");
+ if (ch != EOF && !isspace((unsigned char)ch) && ch != ':') {
+ *p++ = ch;
+ ch = getc(fp);
+ } else {
+ struct servent *s;
+
+ *p++ = 0;
+ s = getservbyname(buff, "udp");
+ if (!s && isdigit((unsigned char)buff[0]))
+ t_port = htons(atoi(buff));
+ else if (!s)
+ die("unknown service `%s' in `" file_SERVER "'", buff);
+ else
+ t_port = s->s_port;
+ state = st_commit;
+ }
+ break;
+
+ /* --- A server has been read successfully --- */
+
+ case st_commit:
+ if (n_serv == max_serv) {
+ max_serv *= 2;
+ serv = xrealloc(serv, max_serv * sizeof(*serv));
+ }
+ serv[n_serv].sin_family = AF_INET;
+ serv[n_serv].sin_addr = t_host;
+ serv[n_serv].sin_port = t_port;
+ n_serv++;
+ state = st_start;
+ p = buff;
+ t_port = port;
+ break;
+
+ /* --- A safety net for a broken parser --- */
+
+ default:
+ die("internal error: can't get here in check__client");
+ break;
+ }
+ }
+ }
+
+ fclose(fp);
+
+ /* --- Now start sending requests --- */
+
+ if (!n_serv)
+ die("no servers specified in `" file_SERVER "'");
+
+ IF_TRACING(TRACE_CLIENT, {
+ size_t i;
+
+ for (i = 0; i < n_serv; i++) {
+ trace(TRACE_CLIENT, "client: server %s port %i",
+ inet_ntoa(serv[i].sin_addr), ntohs(serv[i].sin_port));
+ }
+ })
+ return (check__ask(rq, serv, n_serv));
+}
+
/* --- @check@ --- *
*
* Arguments: @request *rq@ = pointer to request buffer
/* --- Check if we need to talk to a server --- */
- if ((fp = fopen(file_SERVER, "r")) != 0) {
- char buff[64];
- int port;
- int ch;
-
- if (fscanf(fp, " %63[^: \t] ", buff) < 1)
- die("error in `%s'", file_SERVER);
- ch = getc(fp);
- if (ch == ':') {
- char b[64];
- struct servent *se;
-
- fscanf(fp, "%s", b);
- if ((se = getservbyname(b, 0)) != 0)
- port = ntohs(se->s_port);
- else if ((port = atoi(b)) == 0)
- die("error in `%s'", file_SERVER);
- } else {
- struct servent *se;
-
- if ((se = getservbyname(quis(), "udp")) == 0)
- die("no idea which port to use");
- port = ntohs(se->s_port);
- }
- fclose(fp);
- return (check__client(rq, buff, port));
- }
+ if ((fp = fopen(file_SERVER, "r")) != 0)
+ return (check__client(rq, fp));
- /* --- Read the configuration in and go --- */
+ /* --- Otherwise do this all the old-fashioned way --- */
if ((fp = fopen(file_RULES, "r")) == 0) {
die("couldn't read configuration file `%s': %s",
file_RULES, strerror(errno));
}
+ userdb_init();
+ userdb_local();
+ userdb_yp();
name_init();
rule_init();
lexer_scan(fp);
/* -*-c-*-
*
- * $Id: check.h,v 1.1 1997/07/21 13:47:52 mdw Exp $
+ * $Id: check.h,v 1.2 1997/08/04 10:24:21 mdw Exp $
*
* Check validity of requests
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: check.h,v $
- * Revision 1.1 1997/07/21 13:47:52 mdw
+ * Revision 1.2 1997/08/04 10:24:21 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:52 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: class.c,v 1.1 1997/07/21 13:47:52 mdw Exp $
+ * $Id: class.c,v 1.2 1997/08/04 10:24:21 mdw Exp $
*
* Handling classes of things nicely
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: class.c,v $
- * Revision 1.1 1997/07/21 13:47:52 mdw
+ * Revision 1.2 1997/08/04 10:24:21 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:52 mdw
* Initial revision
*
*/
/* --- Local headers --- */
+#include "become.h"
#include "class.h"
#include "set.h"
#include "sym.h"
{
if (~c->type & clType_user)
return (0);
- else if (c == class_all)
+ else if (c == class_all) {
+ T( trace(TRACE_CHECK, "check: user %i matched by all", u); )
return (1);
- else
- return (sym_find(c->t, (char *)&u, sizeof(u), 0, 0) != 0);
+ } else {
+ sym_base *s = sym_find(c->t, (char *)&u, sizeof(u), 0, 0);
+ T( trace(TRACE_CHECK,
+ s ? "check: user %i matched" : "check: user %i not matched",
+ u); )
+ return (s != 0);
+ }
}
/* --- @class_commandMatch@ --- *
if (~c->type & clType_command)
return (0);
- else if (c == class_all)
+ else if (c == class_all) {
+ T( trace(TRACE_CHECK, "check: command `%s' matched by all", p); )
return (1);
- else {
+ } else {
for (sym_createIter(&i, c->t); (s = sym_next(&i)) != 0; ) {
- if (class__wildMatch(s->name, p))
+ if (class__wildMatch(s->name, p)) {
+ T( trace(TRACE_CHECK, "check: command `%s' matched by `%s'",
+ p, s->name); )
return (1);
+ }
}
+ T( trace(TRACE_CHECK, "check: command `%s' not matched", p); )
return (0);
}
}
if (~c->type & clType_host)
return (0);
- else if (c == class_all)
+ else if (c == class_all) {
+ T( trace(TRACE_CHECK, "check: host %s matched by all",
+ inet_ntoa(addr)); )
return (1);
- else {
+ } else {
/* --- Get the dotted-quad and other names for the address --- */
- if ((a = inet_ntoa(addr)) == 0)
+ if ((a = inet_ntoa(addr)) == 0) {
+ T( trace(TRACE_CHECK, "check: couldn't translate address (erk!)"); )
return (0);
- if ((he = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET)) == 0)
+ }
+ if ((he = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET)) == 0) {
+ T( trace(TRACE_CHECK, "check: couldn't resolve hostname for %s", a); )
return (0);
+ }
/* --- Now search the list for a match --- *
*
/* --- Check the dotted-quad name first --- */
- if (class__wildMatch(s->name, a))
+ if (class__wildMatch(s->name, a)) {
+ T( trace(TRACE_CHECK, "check: host address `%s' matched by `%s'",
+ a, s->name); )
return (1);
+ }
/* --- Now try the host's main name --- */
- if (class__wildMatch(s->name, he->h_name))
+ if (class__wildMatch(s->name, he->h_name)) {
+ T( trace(TRACE_CHECK, "check: host name `%s' matched by `%s'",
+ he->h_name, s->name); )
return (1);
+ }
/* --- Now go through all the names --- */
for (p = he->h_aliases; *p; p++) {
- if (class__wildMatch(s->name, *p))
+ if (class__wildMatch(s->name, *p)) {
+ T( trace(TRACE_CHECK, "check: host alias `%s' matched by `%s'",
+ *p, s->name); )
return (1);
+ }
}
}
+
+ T( trace(TRACE_CHECK, "check: couldn't match hostname `%s'",
+ he->h_name); )
return (0);
}
}
/* --- @class_dump@ --- *
*
* Arguments: @classdef *c@ = pointer to a class block
- * @FILE *fp@ = pointer to a stream object
*
* Returns: ---
*
* Use: Dumps the contents of a class to a stream.
*/
-void class_dump(classdef *c, FILE *fp)
+void class_dump(classdef *c)
{
sym_iter i;
sym_base *s;
- /* --- Write a little header block --- */
-
- {
- const char *typetbl[] = {
- "bad class",
- "user",
- "command",
- "user/command",
- "host",
- "host/user",
- "host/command",
- "all",
- };
-
- fprintf(fp,
- "*** Type: %s\n"
- "*** Refs: %u\n"
- "*** \n"
- "*** Items:\n",
- c->type < clType__limit ? typetbl[c->type] : "bad class",
- c->ref);
- }
-
/* --- Dump the table --- */
if (c->type != clType_all) {
for (sym_createIter(&i, c->t); (s = sym_next(&i)) != 0; ) {
switch (c->type) {
case clType_user:
- fprintf(fp, "*** %i\n", *(int *)s->name);
+ trace(TRACE_RULE, " %i", *(int *)s->name);
break;
case clType_command:
case clType_host:
- fputs("*** ", fp);
- fwrite(s->name, s->len, 1, fp);
- putc('\n', fp);
+ trace(TRACE_RULE, " `%s'", s->name);
break;
}
}
}
-
- putc('\n', fp);
+ else
+ trace(TRACE_RULE, " ALL");
}
/*----- That's all, folks -------------------------------------------------*/
/* -*-c-*-
*
- * $Id: class.h,v 1.1 1997/07/21 13:47:52 mdw Exp $
+ * $Id: class.h,v 1.2 1997/08/04 10:24:21 mdw Exp $
*
* Handling classes of things nicely
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: class.h,v $
- * Revision 1.1 1997/07/21 13:47:52 mdw
+ * Revision 1.2 1997/08/04 10:24:21 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:52 mdw
* Initial revision
*
*/
/* --- @class_dump@ --- *
*
* Arguments: @classdef *c@ = pointer to a class block
- * @FILE *fp@ = pointer to a stream object
*
* Returns: ---
*
* Use: Dumps the contents of a class to a stream.
*/
-extern void class_dump(classdef */*c*/, FILE */*fp*/);
+extern void class_dump(classdef */*c*/);
/*----- That's all, folks -------------------------------------------------*/
/* -*-c-*-
*
- * $Id: crypt.c,v 1.1 1997/07/21 13:47:51 mdw Exp $
+ * $Id: crypt.c,v 1.2 1997/08/04 10:24:21 mdw Exp $
*
* Cryptographic transfer of `become' requests
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: crypt.c,v $
- * Revision 1.1 1997/07/21 13:47:51 mdw
+ * Revision 1.2 1997/08/04 10:24:21 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:51 mdw
* Initial revision
*
*/
/* --- Unix headers --- */
#include <sys/types.h>
+#include <sys/time.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
/* --- Local headers --- */
+#include "become.h"
#include "config.h"
#include "crypt.h"
#include "icrypt.h"
#include "idea.h"
#include "md5.h"
+#include "noise.h"
+#include "rand.h"
#include "tx.h"
#include "utils.h"
/*----- Magic numbers -----------------------------------------------------*/
-#define crypt__timeError 15 /* Seconds error to permit */
-#define crypt__seedBits 512 /* Number of random seed bits */
-
-/*----- Dump a block of data ----------------------------------------------*/
-
-/* --- @crypt__dump@ --- *
- *
- * Arguments: @char *p@ = a string to display at the top of the message
- * @unsigned char *buf@ = pointer to a buffer to display
- * @size_t sz@ = size of the buffer
- * @FILE *fp@ = file to dump on
- *
- * Returns: --
- *
- * Use: Dumps a block of data to the terminal. This allows a
- * programmer to examine the traffic between client and server,
- * and possibly locate bugs.
- */
-
-#ifndef NDEBUG
-
-static void crypt__dump(const char *p, const unsigned char *buf,
- int sz, FILE *fp)
-{
- int i;
- fprintf(stderr,"+++ %s\n",p);
- while (sz>0)
- {
- fprintf(stderr,"+++ ");
- for (i=0;i<8;i++)
- {
- if (i<sz)
- fprintf(stderr,"%02x ",buf[i] & 0xff);
- else
- fputs("** ",stderr);
- }
- fputs(": ",stderr);
- for (i=0;i<8;i++)
- putc(i<sz ? (isprint(buf[i]) ? buf[i] : '.') : '*',stderr);
- putc('\n',stderr);
- buf+=8;
- sz-=8;
- }
- putc('\n',stderr);
-}
-
-#else
-
-#define crypt__dump(p, buf, sz, fp) ((void)0)
-
-#endif
+#define crypt__timeError 60 /* Seconds error to permit */
/*----- Main code ---------------------------------------------------------*/
*
* Arguments: @const char *seedfile@ = pointer to name of seed file
* @unsigned char *k@ = our secret key
- * @time_t t@ = the current time
- * @pid_t pid@ = our process id
* @unsigned *sk@ = where to store the session key
* @unsigned char *iv@ = where to store the IV
*
*/
static void crypt__sessionKey(const char *seedfile, unsigned char *k,
- time_t t, pid_t pid,
unsigned char *sk, unsigned char *iv)
{
FILE *fp; /* File handle for reading */
- unsigned char s[crypt__seedBits / 8]; /* Random seed block */
- unsigned char b[4 + 4];
- /* For building the hash block */
+ struct flock l;
+ int ok = 1;
- /* --- Read the old seed in --- *
+ /* --- Open the random seed file --- *
*
- * Interlock with other processes locking this file.
+ * If I can't manage that, create a new one.
*/
- {
-#ifndef TEST_RIG
- struct flock l;
-#endif
-
- if ((fp = fopen(seedfile, "r+")) == 0)
- die("couldn't open random seed file `%s': %s",
- seedfile, strerror(errno));
-
-#ifndef TEST_RIG
- l.l_type = F_WRLCK;
- l.l_whence = SEEK_SET;
- l.l_start = 0;
- l.l_len = 0;
- if (fcntl(fileno(fp), F_SETLKW, &l) < 0)
- die("couldn't lock random number file: %s", strerror(errno));
-#endif
-
- tx_getBits(s, crypt__seedBits, fp);
+ if ((fp = fopen(seedfile, "r+")) == 0) {
+ ok = 0;
+ if ((fp = fopen(seedfile, "w+")) == 0)
+ die("can't create random number file: %s", strerror(errno));
+ rand_clear();
}
- crypt__dump("Initial seed", s, crypt__seedBits / 8, stdout);
-
- /* --- Build a block of data to hash --- */
-
- store32(b + 0, t);
- store32(b + 4, pid);
-
- /* --- Work out the session key --- */
-
- {
- md5 md;
-
- md5_init(&md);
- md5_buffer(&md, s, sizeof(s));
- md5_buffer(&md, b, sizeof(b));
- md5_buffer(&md, k, IDEA_KEYSIZE);
- md5_final(&md, sk);
-
- crypt__dump("Session key", sk, 128 / 8, stdout);
- burn(md);
- }
+ /* --- Lock the seed file against concurrency problems --- */
- /* --- Build the new seed and write it back again --- */
+ l.l_type = F_WRLCK;
+ l.l_whence = SEEK_SET;
+ l.l_start = 0;
+ l.l_len = 0;
+ if (fcntl(fileno(fp), F_SETLKW, &l) < 0)
+ die("can't lock random number file: %s", strerror(errno));
- if (crypt__seedBits > 128) {
- unsigned char tb[MD5_HASHSIZE];
- int i;
+ /* --- Now read the file, and launder the seed --- */
- memcpy(tb, s + crypt__seedBits / 8 - sizeof(tb), sizeof(tb));
- memmove(s + sizeof(tb), s, crypt__seedBits / 8 - sizeof(tb));
- memcpy(s, tb, sizeof(tb));
- for (i = 0; i < sizeof(sk); i++)
- s[i] ^= sk[i];
- burn(tb);
- }
+ if (ok)
+ rand_read(fp);
- /* --- Take the seed we have and hash it again to get an IV --- */
+ /* --- Encrypt the pool using the secret key --- */
{
- unsigned char mdv[MD5_HASHSIZE];
- md5 md;
-
- md5_init(&md);
- md5_buffer(&md, b, sizeof(b));
- md5_buffer(&md, k, IDEA_KEYSIZE);
- md5_buffer(&md, s, sizeof(s));
- md5_final(&md, mdv);
- memcpy(iv, mdv, IDEA_BLKSIZE);
- crypt__dump("IV", iv, IDEA_BLKSIZE, stdout);
- burn(md); burn(mdv);
+ icrypt_job j;
+ icrypt_init(&j, k, 0);
+ rand_encrypt(&j);
+ burn(j);
}
+ /* --- Generate the session key and IV --- */
- /* --- Lock the file again --- *
- *
- * We're closing the file after we've finished, so we don't need to
- * unlock it afterwards.
- */
+ noise_acquire();
+ rand_extract(sk, IDEA_KEYSIZE);
+ rand_extract(iv, IDEA_BLKSIZE);
+
+ IF_TRACING(TRACE_CRYPTO,
+ traceblk(TRACE_CRYPTO, "crypto: session key:", sk, IDEA_KEYSIZE);
+ traceblk(TRACE_CRYPTO, "crypto: initialisation vector:",
+ iv, IDEA_BLKSIZE);
+ );
- crypt__dump("Final seed", s, crypt__seedBits / 8, stdout);
+ /* --- Write the seed back --- */
rewind(fp);
- tx_putBits(s, crypt__seedBits, fp);
+ rand_write(fp);
fclose(fp);
- /* --- Destroy sensitive data --- */
-
- burn(b); burn(s);
}
/* --- @crypt_packRequest@ --- *
store32(buff + crq_from, rq->from);
store32(buff + crq_to, rq->to);
+ /* --- Now generate session keys and things --- */
+
+ crypt__sessionKey(file_RANDSEED, k, sk, buff + crq_iv);
+ memcpy(buff + crq_session, sk, IDEA_KEYSIZE);
+
/* --- The string causes a few problems --- *
*
* There's a good chance that the string will be a good deal shorter than
icrypt_job j;
unsigned char *p;
unsigned u;
+ md5 md;
+ unsigned char qk[IDEA_KEYSIZE];
/* --- Initialise the buffer with junk --- */
srand((unsigned int)(t ^ pid)); /* Seed the (bad) RNG */
for (p = buff + crq_cmd; p < buff + crq_cmd + CMDLEN_MAX; p++) {
- u = rand();
- *p = u ^ (u >> 8);
+ u = rand(); *p = u ^ (u >> 8);
}
/* --- Now make the junk a whole lot harder to predict --- */
p = buff + crq_cmd;
- icrypt_init(&j, p, 0);
- icrypt_encrypt(&j, p, p, CMDLEN_MAX);
- burn(j);
+ md5_init(&md); md5_buffer(&md, p, CMDLEN_MAX); md5_final(&md, qk);
+ icrypt_init(&j, qk, 0); icrypt_encrypt(&j, p, p, CMDLEN_MAX);
+ burn(j); burn(qk); burn(md);
/* --- Copy the string into here --- */
strcpy((char *)buff + crq_cmd, rq->cmd);
}
- /* --- Generate a session key --- */
-
- {
- crypt__sessionKey(file_RANDSEED, k, t, pid, sk, buff + crq_iv);
- memcpy(buff + crq_session, sk, IDEA_KEYSIZE);
- }
-
/* --- Checksum the finished data --- */
{
md5 md;
- unsigned char mdv[MD5_HASHSIZE];
+ unsigned char mdbuf[MD5_HASHSIZE];
md5_init(&md);
md5_buffer(&md, buff + crq_cipher, crq_check - crq_cipher);
- md5_final(&md, mdv);
- memcpy(buff + crq_check, mdv, 4);
- burn(md); burn(mdv);
+ md5_final(&md, mdbuf);
+ memcpy(buff + crq_check, mdbuf, 4);
+ burn(md); burn(mdbuf);
}
/* --- Encrypt the block --- *
{
icrypt_job j;
- crypt__dump("request, before encryption", buff, crq_size, stdout);
+ T( traceblk(TRACE_CRYPTO, "crypto: plaintext request:",
+ buff, crq_size); )
icrypt_init(&j, k, buff + crq_iv);
icrypt_encrypt(&j, buff + crq_session, buff + crq_session, IDEA_KEYSIZE);
buff + crq_cipher, crq_size - crq_cipher);
burn(j);
- crypt__dump("request, after encryption", buff, crq_size, stdout);
+ T( traceblk(TRACE_CRYPTO, "crypto: ciphertext request:",
+ buff, crq_size); )
}
}
icrypt_job j;
- crypt__dump("request, before decryption", buff, crq_size, stdout);
+ T( traceblk(TRACE_CRYPTO, "crypto: ciphertext request:",
+ buff, crq_size); )
icrypt_init(&j, k, buff + crq_iv);
icrypt_decrypt(&j, buff + crq_session, buff + crq_session, IDEA_KEYSIZE);
memset(buff + crq_session, 0, IDEA_KEYSIZE); /* Burn, baby, burn */
burn(j);
- crypt__dump("request, after decryption", buff, crq_size, stdout);
+ T( traceblk(TRACE_CRYPTO, "crypto: plaintext request:",
+ buff, crq_size); )
}
{
/* --- Check the validity of the data therein --- */
md5 md;
- unsigned char mdv[MD5_HASHSIZE];
+ unsigned char mdbuf[MD5_HASHSIZE];
md5_init(&md);
md5_buffer(&md, buff + crq_cipher, crq_check - crq_cipher);
- md5_final(&md, mdv);
- if (memcmp(mdv, buff + crq_check, 4) != 0) {
+ md5_final(&md, mdbuf);
+ if (memcmp(mdbuf, buff + crq_check, 4) != 0) {
syslog(LOG_INFO, "packet rejected: bad checksum");
+ T( trace(TRACE_CRYPTO, "crypto: bad checksum on incoming request"); )
return (0);
}
- burn(md); burn(mdv);
+ burn(md); burn(mdbuf);
}
{
if (t - u > crypt__timeError || u - t > crypt__timeError) {
syslog(LOG_INFO, "packet rejected: bad time");
+ T( trace(TRACE_CRYPTO, "crypto: bad time on incoming request"); )
return (0);
}
memcpy(rpl + crp_time, buff + crq_time, 8);
/* --- Done --- */
+ T( trace(TRACE_CRYPTO, "crypto: valid request received"); )
return (1);
}
/* --- Build the checksum --- */
md5 md;
- unsigned char mdv[MD5_HASHSIZE];
+ unsigned char mdbuf[MD5_HASHSIZE];
md5_init(&md);
md5_buffer(&md, buff + crp_cipher, crp_check - crp_cipher);
- md5_final(&md, mdv);
- memcpy(buff + crp_check, mdv, 4);
- burn(md); burn(mdv);
+ md5_final(&md, mdbuf);
+ memcpy(buff + crp_check, mdbuf, 4);
+ burn(md); burn(mdbuf);
}
{
/* --- Encrypt the buffer --- */
icrypt_job j;
+
+ T( traceblk(TRACE_CRYPTO, "crypto: plaintext reply:", buff, crp_size); )
+
icrypt_init(&j, sk, buff + crp_iv);
- crypt__dump("reply, before encryption", buff, crp_size, stdout);
icrypt_encrypt(&j, buff + crp_cipher,
buff + crp_cipher, crp_size - crp_cipher);
- crypt__dump("reply, after encryption", buff, crp_size, stdout);
burn(j);
+
+ T( traceblk(TRACE_CRYPTO, "crypto: ciphertext reply:", buff, crp_size); )
}
}
/* --- Decrypt my reply block --- */
icrypt_job j;
+
+ T( traceblk(TRACE_CRYPTO, "crypto: ciphertext reply:", buff, crp_size); )
+
icrypt_init(&j, sk, buff + crp_iv);
- crypt__dump("reply, before decryption", buff, crp_size, stdout);
icrypt_decrypt(&j, buff + crp_cipher,
buff + crp_cipher, crp_size - crp_cipher);
- crypt__dump("reply, after decryption", buff, crp_size, stdout);
burn(j);
+
+ T( traceblk(TRACE_CRYPTO, "crypto: plaintext reply:", buff, crp_size); )
}
{
/* --- Check validity --- */
md5 md;
- unsigned char mdv[MD5_HASHSIZE];
+ unsigned char mdbuf[MD5_HASHSIZE];
char b[8];
/* --- Check the checksum --- */
md5_init(&md);
md5_buffer(&md, buff + crp_cipher, crp_check - crp_cipher);
- md5_final(&md, mdv);
- if (memcmp(buff + crp_check, mdv, 4) != 0) {
+ md5_final(&md, mdbuf);
+ if (memcmp(buff + crp_check, mdbuf, 4) != 0) {
syslog(LOG_INFO, "reply rejected: bad checksum");
+ T( trace(TRACE_CRYPTO, "crypto: bad checksum on reply"); )
return (-1);
}
store32(b + 0, t); store32(b + 4, pid);
if (memcmp(b, buff + crp_time, sizeof(b)) != 0) {
syslog(LOG_INFO, "reply rejected: bad identification marker");
+ T( trace(TRACE_CRYPTO, "crypto: bad id on reply"); )
return (-1);
}
}
/* --- Return the value --- */
+ T( trace(TRACE_CRYPTO, "crypto: valid reply received"); )
return (buff[crp_answer]);
}
int main(int argc, char *argv[])
{
- time_t t = time(0);
- pid_t pid = getpid();
unsigned char buff[8];
unsigned char sk[IDEA_KEYSIZE], k[IDEA_KEYSIZE];
FILE *fp;
ego(argv[0]);
+ traceon(stdout, TRACE_CRYPTO);
if (argc < 3)
die("bad args");
fp = fopen(argv[1], "r");
die("fopen: %s", strerror(errno));
tx_getBits(k, 128, fp);
fclose(fp);
- crypt__sessionKey(argv[2], k, t, pid, sk, buff);
+ crypt__sessionKey(argv[2], k, sk, buff);
return (0);
}
/* -*-c-*-
*
- * $Id: crypt.h,v 1.1 1997/07/21 13:47:51 mdw Exp $
+ * $Id: crypt.h,v 1.2 1997/08/04 10:24:21 mdw Exp $
*
* Cryptographic transfer of `become' requests
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: crypt.h,v $
- * Revision 1.1 1997/07/21 13:47:51 mdw
+ * Revision 1.2 1997/08/04 10:24:21 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:51 mdw
* Initial revision
*
*/
crp_size = crp_check + 4 /* Size of encrypted reply */
};
-/*----- Macros ------------------------------------------------------------*/
-
-/* --- @burn@ --- *
- *
- * Arguments: @obj@ = some object
- *
- * Use: Writes zero bytes over the object.
- */
-
-#define burn(obj) ((void)memset(&obj, 0, sizeof(obj)))
-
/*----- Functions provided ------------------------------------------------*/
/* --- @crypt_packRequest@ --- *
/* -*-c-*-
*
- * $Id: daemon.c,v 1.1 1997/07/21 13:47:50 mdw Exp $
+ * $Id: daemon.c,v 1.2 1997/08/04 10:24:21 mdw Exp $
*
* Running a `become' daemon
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: daemon.c,v $
- * Revision 1.1 1997/07/21 13:47:50 mdw
+ * Revision 1.2 1997/08/04 10:24:21 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:50 mdw
* Initial revision
*
*/
if (!daemon__readKey)
daemon_readKey(file_KEY);
daemon__rescan = 0;
+ T( trace(TRACE_DAEMON, "daemon: read config file"); )
return (0);
}
if (recvfrom(fd, (char *)buff, sizeof(buff), 0,
(struct sockaddr *)&sin, &slen) < 0) {
+ T( trace(TRACE_DAEMON, "daemon: error reading packet: %s",
+ strerror(errno)); )
syslog(LOG_INFO, "duff packet received: %e");
return;
}
he ? he->h_name : inet_ntoa(sin.sin_addr),
sizeof(sender));
syslog(LOG_DEBUG, "packet received from %s", sender);
+ T( trace(TRACE_DAEMON, "daemon: received request from %s", sender); )
}
/* --- Unpack the block --- */
if (crypt_unpackRequest(&rq, buff, daemon__key, sk, rpl) == 0) {
burn(buff);
+ T( trace(TRACE_DAEMON, "daemon: received corrupt or invalid request"); )
syslog(LOG_INFO, "packet from %s rejected", sender);
return;
}
/* --- Send the reply off --- */
sendto(fd, (char *)rpl, crp_size, 0, (struct sockaddr *)&sin, sizeof(sin));
+ T( trace(TRACE_DAEMON, "daemon: reply sent"); )
burn(rpl);
}
fprintf(fp, "%lu\n", (unsigned long)getpid());
fclose(fp);
}
+ T( trace(TRACE_DAEMON, "daemon: forked to pid %li", (long)getpid()); )
}
#endif
/* --- Program in daemon death mode --- */
if (setjmp(daemon__dieBuf)) {
- syslog(LOG_NOTICE, "killed by signal type %i", daemon__signum);
- remove(file_PID);
- exit(0);
- }
+#ifdef TRACING
+ if (daemon__signum == SIGQUIT && tracing() & TRACE_RULE) {
+ T( rule_dump(); )
+ signal(SIGQUIT, daemon__die);
+ } else
+#endif
+ {
+ T( trace(TRACE_DAEMON, "daemon: killed by signal %i",
+ daemon__signum); )
+ syslog(LOG_NOTICE, "killed by signal type %i", daemon__signum);
+ remove(file_PID);
+ exit(0);
+ }
+ } else {
- /* --- Set signal handlers --- */
+ /* --- Set signal handlers --- */
- signal(SIGHUP, daemon__restart);
- signal(SIGQUIT, daemon__restart);
- signal(SIGINT, daemon__die);
- signal(SIGTERM, daemon__die);
- signal(SIGSEGV, daemon__die);
- signal(SIGFPE, daemon__die);
- signal(SIGBUS, daemon__die);
+ signal(SIGHUP, daemon__restart);
+ signal(SIGQUIT, daemon__die);
+ signal(SIGINT, daemon__die);
+ signal(SIGTERM, daemon__die);
+ signal(SIGSEGV, daemon__die);
+ signal(SIGFPE, daemon__die);
+ signal(SIGBUS, daemon__die);
+ }
/* --- Now wait for something exciting to happen --- *
*
/* --- Now wait for something interesting --- */
+ T( trace(TRACE_DAEMON, "daemon: waiting for requests"); )
i = select(FD_SETSIZE, &fds, 0, 0, 0);
/* --- Now, see if I need to rescan the config --- */
/* -*-c-*-
*
- * $Id: daemon.h,v 1.1 1997/07/21 13:47:50 mdw Exp $
+ * $Id: daemon.h,v 1.2 1997/08/04 10:24:21 mdw Exp $
*
* Running a `become' daemon
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: daemon.h,v $
- * Revision 1.1 1997/07/21 13:47:50 mdw
+ * Revision 1.2 1997/08/04 10:24:21 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:50 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: dbutils.h,v 1.1 1997/07/21 13:47:50 mdw Exp $
+ * $Id: dbutils.h,v 1.2 1997/08/04 10:24:22 mdw Exp $
*
* Debugging things
*
/*----- Revision history --------------------------------------------------*
*
* $Log: dbutils.h,v $
- * Revision 1.1 1997/07/21 13:47:50 mdw
+ * Revision 1.2 1997/08/04 10:24:22 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:50 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: icrypt.c,v 1.1 1997/07/21 13:47:49 mdw Exp $
+ * $Id: icrypt.c,v 1.2 1997/08/04 10:24:22 mdw Exp $
*
* Higher level IDEA encryption
*
* (c) 1997 Mark Wooding
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: icrypt.c,v $
- * Revision 1.1 1997/07/21 13:47:49 mdw
+ * Revision 1.2 1997/08/04 10:24:22 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:49 mdw
* Initial revision
*
*/
{
char *pass = getpass("Password: ");
+ unsigned char k[IDEA_KEYSIZE];
md5_init(&md);
md5_buffer(&md, pass, strlen(pass));
memset(pass, 0, strlen(pass));
- md5_final(&md);
+ md5_final(&md, k);
- icrypt_init(&j, md.val, 0);
+ icrypt_init(&j, k, 0);
}
if (optind >= argc)
/* -*-c-*-
*
- * $Id: icrypt.h,v 1.1 1997/07/21 13:47:49 mdw Exp $
+ * $Id: icrypt.h,v 1.2 1997/08/04 10:24:22 mdw Exp $
*
* Higher level IDEA encryption
*
* (c) 1997 Mark Wooding
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: icrypt.h,v $
- * Revision 1.1 1997/07/21 13:47:49 mdw
+ * Revision 1.2 1997/08/04 10:24:22 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:49 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: idea.c,v 1.1 1997/07/21 13:47:49 mdw Exp $
+ * $Id: idea.c,v 1.2 1997/08/04 10:24:22 mdw Exp $
*
* IDEA encryption routines
* Based on Straylight ARM assembler routines
* (c) 1996, 1997 Mark Wooding
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: idea.c,v $
- * Revision 1.1 1997/07/21 13:47:49 mdw
+ * Revision 1.2 1997/08/04 10:24:22 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:49 mdw
* Initial revision
*
*/
/*----- Header files ------------------------------------------------------*/
#include <stdio.h>
+#include <string.h>
#include "config.h"
#include "idea.h"
/* -*-c-*-
*
- * $Id: idea.h,v 1.1 1997/07/21 13:47:48 mdw Exp $
+ * $Id: idea.h,v 1.2 1997/08/04 10:24:22 mdw Exp $
*
* IDEA encryption routines
* Based on Straylight ARM assembler routines
* (c) 1996, 1997 Mark Wooding
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: idea.h,v $
- * Revision 1.1 1997/07/21 13:47:48 mdw
+ * Revision 1.2 1997/08/04 10:24:22 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:48 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: keygen.c,v 1.1 1997/07/21 13:47:48 mdw Exp $
+ * $Id: keygen.c,v 1.2 1997/08/04 10:24:23 mdw Exp $
*
* Key generation
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: keygen.c,v $
- * Revision 1.1 1997/07/21 13:47:48 mdw
+ * Revision 1.2 1997/08/04 10:24:23 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:48 mdw
* Initial revision
*
*/
unsigned long fact = 1000000 / CLOCKS_PER_SEC;
fprintf(kg__ttyfp,
-"I need to get %i random bits; I'll do this by timing your keypresses.\n"
+"I need to get %lu random bits; I'll do this by timing your keypresses.\n"
"Please type some arbitrary text until I say `done'.\n",
- sz);
+ (unsigned long)sz);
{
struct timeval tv;
/* --- Print current status --- */
- fprintf(kg__ttyfp, "\r%5i...", sz);
+ fprintf(kg__ttyfp, "\r%5lu...", (unsigned long)sz);
fflush(kg__ttyfp);
/* --- Read the next character --- */
/* -*-c-*-
*
- * $Id: lexer.h,v 1.1 1997/07/21 13:47:48 mdw Exp $
+ * $Id: lexer.h,v 1.2 1997/08/04 10:24:23 mdw Exp $
*
* Lexical analyser for `become.conf' files
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: lexer.h,v $
- * Revision 1.1 1997/07/21 13:47:48 mdw
+ * Revision 1.2 1997/08/04 10:24:23 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:48 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: lexer.l,v 1.1 1997/07/21 13:47:48 mdw Exp $
+ * $Id: lexer.l,v 1.2 1997/08/04 10:24:23 mdw Exp $
*
* Lexical analyser for `become.conf' files
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: lexer.l,v $
- * Revision 1.1 1997/07/21 13:47:48 mdw
+ * Revision 1.2 1997/08/04 10:24:23 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:48 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: md5.c,v 1.1 1997/07/21 13:47:47 mdw Exp $
+ * $Id: md5.c,v 1.2 1997/08/04 10:24:23 mdw Exp $
*
* MD-5 secure hash routines
* Based on RSA MD-5 code
* (c) 1996, 1997 Mark Wooding
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: md5.c,v $
- * Revision 1.1 1997/07/21 13:47:47 mdw
+ * Revision 1.2 1997/08/04 10:24:23 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:47 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: md5.h,v 1.1 1997/07/21 13:47:47 mdw Exp $
+ * $Id: md5.h,v 1.2 1997/08/04 10:24:23 mdw Exp $
*
* MD-5 secure hash routines
* Based on RSA MD-5 code
* (c) 1996, 1997 Mark Wooding
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: md5.h,v $
- * Revision 1.1 1997/07/21 13:47:47 mdw
+ * Revision 1.2 1997/08/04 10:24:23 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:47 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: mdwopt.c,v 1.1 1997/07/21 13:47:47 mdw Exp $
+ * $Id: mdwopt.c,v 1.2 1997/08/04 10:24:23 mdw Exp $
*
* Options parsing, similar to GNU @getopt_long@
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `mdwopt'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `mdwopt'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: mdwopt.c,v $
- * Revision 1.1 1997/07/21 13:47:47 mdw
- * Initial revision
+ * Revision 1.2 1997/08/04 10:24:23 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.4 1997/07/29 21:11:35 mdw
+ * Reformatted. Fixed buffer overflow when dealing with environment
+ * variables. Included NT in list of daft operating systems with `\' as a
+ * path separator. Fixed address of the FSF.
*
* Revision 1.3 1997/02/26 00:41:10 mdw
* Added GPL notice to the top. Slight formatting changes.
#if defined(__riscos)
# define PATHSEP '.'
-#elif defined(__OS2__) || defined(__MSDOS__)
+#elif defined(__OS2__) || defined(__MSDOS__) || defined(__WINNT__)
# define PATHSEP '\\'
#else /* Assume a sane filing system */
# define PATHSEP '/'
/* -*-c-*-
*
- * $Id: mdwopt.h,v 1.1 1997/07/21 13:47:47 mdw Exp $
+ * $Id: mdwopt.h,v 1.2 1997/08/04 10:24:24 mdw Exp $
*
* Options parsing, similar to GNU @getopt_long@
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `mdwopt'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `mdwopt'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: mdwopt.h,v $
- * Revision 1.1 1997/07/21 13:47:47 mdw
- * Initial revision
+ * Revision 1.2 1997/08/04 10:24:24 mdw
+ * Sources placed under CVS control.
*
- * Revision 1.4 1997/02/26 00:39:55 mdw
- * Added GPL notice to the top. Slight formatting changes. Commented out
- * arguments to functions.
+ * Revision 1.4 1997/07/29 21:11:49 mdw
+ * Fixed address of the FSF.
*
* Revision 1.3 1996/12/31 19:41:33 mdw
* Formatting changes.
/* -*-c-*-
*
- * $Id: name.c,v 1.1 1997/07/21 13:47:46 mdw Exp $
+ * $Id: name.c,v 1.2 1997/08/04 10:24:24 mdw Exp $
*
* Looking up of names in symbol tables
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: name.c,v $
- * Revision 1.1 1997/07/21 13:47:46 mdw
+ * Revision 1.2 1997/08/04 10:24:24 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:46 mdw
* Initial revision
*
*/
/* --- Unix headers --- */
+#include "config.h"
+
+#ifdef HAVE_YP
+# include <rpcsvc/ypclnt.h>
+# include <rpcsvc/yp_prot.h>
+#endif
+
#include <grp.h>
#include <pwd.h>
/* --- Local headers --- */
+#include "become.h"
#include "class.h"
#include "name.h"
#include "sym.h"
/*----- Main code ---------------------------------------------------------*/
-/* --- @name_init@ --- *
+/* --- @name__users@ --- *
*
* Arguments: ---
*
* Returns: ---
*
- * Use: Initialises the name table. Requires the user database to
- * be populated (see @userdb_local@ and @userdb_yp@).
+ * Use: Adds all of the users registered with the user database to
+ * the name table. Also adds the users' primary groups.
*/
-void name_init(void)
+static void name__users(void)
{
- /* --- Initialise the name table --- */
-
- sym_createTable(&name__table);
+ struct passwd *pw;
+ struct group *gr;
- /* --- Insert all the users and groups into the table --- */
+ userdb_iterateUsers();
+ while ((pw = userdb_nextUser()) != 0) {
+ unsigned f;
+ name *n;
+ int u;
- {
- struct passwd *pw;
- struct group *gr;
+ /* --- First, add the user to the table --- */
- userdb_iterateUsers();
- while ((pw = userdb_nextUser()) != 0) {
- unsigned f;
- name *n;
- int u;
+ n = sym_find(&name__table, pw->pw_name, -1, sizeof(name), &f);
+ if (!f) {
+ sym_table *t = xmalloc(sizeof(*t));
+ sym_createTable(t);
+ n->c = class_create(clType_user, t);
+ }
+ u = pw->pw_uid;
+ sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0);
- /* --- First, add the user to the table --- */
+ /* --- Now handle the user's default group --- */
- n = sym_find(&name__table, pw->pw_name, -1, sizeof(name), &f);
+ if ((gr = userdb_groupById(pw->pw_gid)) != 0) {
+ n = sym_find(&name__table, gr->gr_name, -1, sizeof(name), &f);
if (!f) {
sym_table *t = xmalloc(sizeof(*t));
sym_createTable(t);
n->c = class_create(clType_user, t);
}
- u = pw->pw_uid;
sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0);
+ }
+ }
+}
- /* --- Now handle the user's default group --- */
+/* --- @name__groups@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Adds users into all of their supplementary groups.
+ */
+
+static void name__groups(void)
+{
+ struct group *gr;
+ struct passwd *pw;
+ char **p;
+
+ userdb_iterateGroups();
+ while ((gr = userdb_nextGroup()) != 0) {
+ unsigned f;
+ name *n;
+ int u;
- if ((gr = userdb_groupById(pw->pw_gid)) != 0) {
- n = sym_find(&name__table, gr->gr_name, -1, sizeof(name), &f);
- if (!f) {
- sym_table *t = xmalloc(sizeof(*t));
- sym_createTable(t);
- n->c = class_create(clType_user, t);
- }
+ /* --- Add the group name to the table --- */
+
+ n = sym_find(&name__table, gr->gr_name, -1, sizeof(name), &f);
+ if (!f) {
+ sym_table *t = xmalloc(sizeof(*t));
+ sym_createTable(t);
+ n->c = class_create(clType_user, t);
+ }
+
+ /* --- Now add all of the members --- */
+
+ for (p = gr->gr_mem; *p; p++) {
+ if ((pw = userdb_userByName(*p)) != 0) {
+ u = pw->pw_uid;
sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0);
}
}
}
+}
- /* --- Now get the subsidiary groups --- */
+/* --- @name_init@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Initialises the name table. Requires the user database to
+ * be populated (see @userdb_local@ and @userdb_yp@).
+ */
- {
- struct group *gr;
- struct passwd *pw;
- char **p;
+void name_init(void)
+{
+ /* --- Initialise the name table --- */
- userdb_iterateGroups();
- while ((gr = userdb_nextGroup()) != 0) {
- unsigned f;
- name *n;
- int u;
+ sym_createTable(&name__table);
- n = sym_find(&name__table, gr->gr_name, -1, sizeof(name), &f);
- if (!f) {
- sym_table *t = xmalloc(sizeof(*t));
- sym_createTable(t);
- n->c = class_create(clType_user, t);
- }
+ /* --- Add everyone into the table --- */
- for (p = gr->gr_mem; *p; p++) {
- if ((pw = userdb_userByName(*p)) != 0) {
- u = pw->pw_uid;
- sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0);
- }
- }
- }
- }
+ name__users();
+ name__groups();
/* --- Finally add in the `all' class --- *
*
/* --- @name_dump@ --- *
*
- * Arguments: @FILE *fp@ = stream to dump on
+ * Arguments: ---
*
* Returns: ---
*
* Use: Dumps a complete listing of the symbol table.
*/
-void name_dump(FILE *fp)
+void name_dump(void)
{
sym_iter i;
name *n;
+ trace(TRACE_DEBUG, "name: dumping names");
for (sym_createIter(&i, &name__table); (n = sym_next(&i)) != 0; ) {
- fprintf(fp, "\n--- name `%s'\n", n->base.name);
- class_dump(n->c, fp);
+ trace(TRACE_DEBUG, "name: dumping `%s'", n->base.name);
+ class_dump(n->c);
}
}
userdb_init();
userdb_local();
userdb_yp();
+ ego("name-test");
+ traceon(stdout, TRACE_DEBUG);
name_init();
- name_dump(stdout);
+ name_dump();
return (0);
}
/* -*-c-*-
*
- * $Id: name.h,v 1.1 1997/07/21 13:47:46 mdw Exp $
+ * $Id: name.h,v 1.2 1997/08/04 10:24:24 mdw Exp $
*
* Looking up of names in symbol tables
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: name.h,v $
- * Revision 1.1 1997/07/21 13:47:46 mdw
+ * Revision 1.2 1997/08/04 10:24:24 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:46 mdw
* Initial revision
*
*/
/* --- @name_dump@ --- *
*
- * Arguments: @FILE *fp@ = stream to dump on
+ * Arguments: ---
*
* Returns: ---
*
* Use: Dumps a complete listing of the symbol table.
*/
-extern void name_dump(FILE */*fp*/);
+extern void name_dump(void);
/*----- That's all, folks -------------------------------------------------*/
/* -*-c-*-
*
- * $Id: parser.h,v 1.1 1997/07/21 13:47:46 mdw Exp $
+ * $Id: parser.h,v 1.2 1997/08/04 10:24:24 mdw Exp $
*
* Parser for `become.conf' files
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: parser.h,v $
- * Revision 1.1 1997/07/21 13:47:46 mdw
+ * Revision 1.2 1997/08/04 10:24:24 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:46 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: parser.y,v 1.1 1997/07/21 13:47:45 mdw Exp $
+ * $Id: parser.y,v 1.2 1997/08/04 10:24:24 mdw Exp $
*
* Parser for `become.conf' files
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: parser.y,v $
- * Revision 1.1 1997/07/21 13:47:45 mdw
+ * Revision 1.2 1997/08/04 10:24:24 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:45 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: rule.c,v 1.1 1997/07/21 13:47:45 mdw Exp $
+ * $Id: rule.c,v 1.2 1997/08/04 10:24:25 mdw Exp $
*
* Managing rule sets
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: rule.c,v $
- * Revision 1.1 1997/07/21 13:47:45 mdw
+ * Revision 1.2 1997/08/04 10:24:25 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:45 mdw
* Initial revision
*
*/
#include <stdlib.h>
#include <string.h>
+/* --- Unix headers --- */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+
/* --- Local headers --- */
#include "become.h"
#include "class.h"
#include "rule.h"
+#include "userdb.h"
#include "utils.h"
/*----- Type definitions --------------------------------------------------*/
int rule_check(request *r)
{
- rule *rr = rule__list;
+ rule *rr;
+
+ /* --- Trace out the request we're checking --- */
+
+ IF_TRACING(TRACE_CHECK, {
+ struct passwd *pw_from = userdb_userById(r->from);
+ struct passwd *pw_to = userdb_userById(r->to);
+ struct hostent *h = gethostbyaddr((char *)&r->host, sizeof(r->host),
+ AF_INET);
+
+ trace(TRACE_CHECK, "check: request from %s (%li) to become %s (%li)",
+ pw_from ? pw_from->pw_name : "<unknown>", (long)r->from,
+ pw_to ? pw_to->pw_name : "<unknown>", (long)r->to);
+ trace(TRACE_CHECK, "check: ... at %s (%s) for `%s'",
+ h ? h->h_name : "<unknown>", inet_ntoa(r->host), r->cmd);
+ })
+
+ /* --- Search the rule list --- */
+
+ for (rr = rule__list; rr; rr = rr->next) {
+
+ /* --- Trace out the rule --- */
+
+ IF_TRACING(TRACE_RULE, {
+ trace(TRACE_RULE, "rule: check against rule...");
+ trace(TRACE_RULE, " from"); class_dump(rr->from);
+ trace(TRACE_RULE, " to"); class_dump(rr->to);
+ trace(TRACE_RULE, " cmd"); class_dump(rr->cmd);
+ trace(TRACE_RULE, " host"); class_dump(rr->host);
+ })
+
+ /* --- Check the rule --- */
- while (rr) {
if (class_userMatch(rr->from, r->from) &&
class_userMatch(rr->to, r->to) &&
class_commandMatch(rr->cmd, r->cmd) &&
- class_hostMatch(rr->host, r->host))
+ class_hostMatch(rr->host, r->host)) {
+ T( trace(TRACE_CHECK, "check: rule matched -- granting permission"); )
return (1);
- rr = rr->next;
+ }
}
+
+ /* --- Failed to match --- */
+
+ T( trace(TRACE_CHECK, "check: no rules matched -- permission denied"); )
return (0);
}
+/* --- @rule_dump@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Dumps a map of the current ruleset to the trace output.
+ */
+
+void rule_dump(void)
+{
+ rule *rr = rule__list;
+
+ trace(TRACE_RULE, "rule: dumping rules");
+ while (rr) {
+ trace(TRACE_RULE, "rule dump...");
+ trace(TRACE_RULE, " from"); class_dump(rr->from);
+ trace(TRACE_RULE, " to"); class_dump(rr->to);
+ trace(TRACE_RULE, " cmd"); class_dump(rr->cmd);
+ trace(TRACE_RULE, " host"); class_dump(rr->host);
+ rr = rr->next;
+ }
+ trace(TRACE_RULE, "rule: dump finished");
+}
+
/*----- That's all, folks -------------------------------------------------*/
/* -*-c-*-
*
- * $Id: rule.h,v 1.1 1997/07/21 13:47:45 mdw Exp $
+ * $Id: rule.h,v 1.2 1997/08/04 10:24:25 mdw Exp $
*
* Managing rule sets
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: rule.h,v $
- * Revision 1.1 1997/07/21 13:47:45 mdw
+ * Revision 1.2 1997/08/04 10:24:25 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:45 mdw
* Initial revision
*
*/
extern int rule_check(request */*r*/);
+/* --- @rule_dump@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Dumps a map of the current ruleset to the trace output.
+ */
+
+extern void rule_dump(void);
+
/*----- That's all, folks -------------------------------------------------*/
#ifdef __cplusplus
/* -*-c-*-
*
- * $Id: set.c,v 1.1 1997/07/21 13:47:44 mdw Exp $
+ * $Id: set.c,v 1.2 1997/08/04 10:24:25 mdw Exp $
*
* Management of sets (for the use of the class expression handler)
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: set.c,v $
- * Revision 1.1 1997/07/21 13:47:44 mdw
+ * Revision 1.2 1997/08/04 10:24:25 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:44 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: set.h,v 1.1 1997/07/21 13:47:44 mdw Exp $
+ * $Id: set.h,v 1.2 1997/08/04 10:24:25 mdw Exp $
*
* Management of sets (for the use of the class expression handler)
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: set.h,v $
- * Revision 1.1 1997/07/21 13:47:44 mdw
+ * Revision 1.2 1997/08/04 10:24:25 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:44 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: sym.c,v 1.1 1997/07/21 13:47:44 mdw Exp $
+ * $Id: sym.c,v 1.2 1997/08/04 10:24:25 mdw Exp $
*
* Symbol table management
*
* (c) 1996 Straylight
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: sym.c,v $
- * Revision 1.1 1997/07/21 13:47:44 mdw
+ * Revision 1.2 1997/08/04 10:24:25 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:44 mdw
* Initial revision
*
*/
case 0: {
sym_word *w;
- printf("find `%s'\n", line[i]);
+ /* printf("find `%s'\n", line[i]); */
+ if ((rand() & 1023) == 0) {
+ putchar('.'); fflush(stdout);
+ }
w = sym_find(&tbl, line[i], -1, 0, 0);
if (w != flag[i])
unsigned f;
sym_word *w;
- printf("create `%s'\n", line[i]);
+ /* printf("create `%s'\n", line[i]); */
+ if ((rand() & 1023) == 0) {
+ putchar('+'); fflush(stdout);
+ }
w = sym_find(&tbl, line[i], -1, sizeof(sym_word), &f);
if (f)
case 2: {
sym_iter it;
sym_word *w, **ntbl;
+ int v = (rand() % entries) == 0;
+ if (!v)
+ break;
+ printf("\niterated %i entries\n", entries);
+ break;
printf("iterate\n");
case 3: {
sym_base *b;
int v = rand() & 255 ? 0 : 1;
+ break;
printf("dump\n");
case 4: {
if (flag[i]) {
- printf("remove `%s'\n", flag[i]->base.name);
+ /* printf("remove `%s'\n", flag[i]->base.name); */
+ if ((rand() & 1023) == 0) {
+ putchar('-'); fflush(stdout);
+ }
sym_remove(&tbl, flag[i]);
flag[i] = 0;
entries--;
/* -*-c-*-
*
- * $Id: sym.h,v 1.1 1997/07/21 13:47:43 mdw Exp $
+ * $Id: sym.h,v 1.2 1997/08/04 10:24:25 mdw Exp $
*
* Symbol table management
*
* (c) 1996 Straylight
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: sym.h,v $
- * Revision 1.1 1997/07/21 13:47:43 mdw
+ * Revision 1.2 1997/08/04 10:24:25 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:43 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: tx.c,v 1.1 1997/07/21 13:47:43 mdw Exp $
+ * $Id: tx.c,v 1.2 1997/08/04 10:24:25 mdw Exp $
*
* Transfer for keys and other large integers
*
* (c) 1997 Mark Wooding
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: tx.c,v $
- * Revision 1.1 1997/07/21 13:47:43 mdw
+ * Revision 1.2 1997/08/04 10:24:25 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:43 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: tx.h,v 1.1 1997/07/21 13:47:43 mdw Exp $
+ * $Id: tx.h,v 1.2 1997/08/04 10:24:26 mdw Exp $
*
* Transfer for keys and other large integers
*
* (c) 1997 Mark Wooding
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: tx.h,v $
- * Revision 1.1 1997/07/21 13:47:43 mdw
+ * Revision 1.2 1997/08/04 10:24:26 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:43 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: userdb.c,v 1.1 1997/07/21 13:47:43 mdw Exp $
+ * $Id: userdb.c,v 1.2 1997/08/04 10:24:26 mdw Exp $
*
* User database management
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: userdb.c,v $
- * Revision 1.1 1997/07/21 13:47:43 mdw
+ * Revision 1.2 1997/08/04 10:24:26 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:43 mdw
* Initial revision
*
*/
/* --- Unix headers --- */
+#include "config.h"
+
#include <sys/types.h>
+#ifdef HAVE_YP
+# include <rpcsvc/ypclnt.h>
+# include <rpcsvc/yp_prot.h>
+#endif
+
#include <grp.h>
#include <pwd.h>
#include <unistd.h>
/* --- Local headers --- */
-#include "config.h"
#include "sym.h"
#include "userdb.h"
#include "utils.h"
free(gr);
}
-/*----- Higher-level functions --------------------------------------------*/
-
-/* --- @userdb_local@ --- *
- *
- * Arguments: ---
- *
- * Returns: ---
- *
- * Use: Reads the local list of users into the maps.
- */
-
-void userdb_local(void)
-{
- D( printf("adding local users...\n"); )
-
- /* --- Fetch users first --- */
-
- {
- struct passwd *pw;
-
- setpwent();
- while ((pw = getpwent()) != 0) {
- D( userdb__dumpUser(pw, stdout); )
- if (!userdb__byName(&userdb__users, pw->pw_name))
- userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid,
- userdb_copyUser(pw));
- }
- endpwent();
- }
-
- /* --- Then fetch groups --- */
-
- {
- struct group *gr;
-
- setgrent();
- while ((gr = getgrent()) != 0) {
- D( userdb__dumpGroup(gr, stdout); )
- if (!userdb__byName(&userdb__groups, gr->gr_name))
- userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid,
- userdb_copyGroup(gr));
- }
- endgrent();
- }
-}
-
-/* --- @userdb__getLine@ --- *
- *
- * Arguments: @char *buff@ = pointer to buffer to read into
- * @size_t sz@ = size of the buffer
- * @FILE *fp@ = pointer to stream to read on
- *
- * Returns: Zero if something didn't work.
- *
- * Use: Reads a line into the buffer. If the line didn't fit, bits
- * of it are thrown away. The newline character is not
- * included.
- */
-
-static char *userdb__getLine(char *buff, size_t sz, FILE *fp)
-{
- if ((buff = fgets(buff, sz, fp)) == 0)
- return (0);
- sz = strlen(buff) - 1;
- if (buff[sz] == '\n')
- buff[sz] = 0;
- else for (;;) {
- int ch = getc(fp);
- if (ch == '\n' || ch == EOF)
- break;
- }
- return (buff);
-}
-
-/* --- @userdb_yp@ --- *
- *
- * Arguments: ---
- *
- * Returns: ---
- *
- * Use: Fetches the YP database of users.
- */
-
-void userdb_yp(void)
-{
-
-#ifdef HAVE_YP
-
- char line[1024];
- FILE *fp;
-
- D( printf("adding nis users\n"); )
-
- /* --- First, users --- */
-
- if ((fp = popen("ypcat passwd", "r")) != 0) {
- while (userdb__getLine(line, sizeof(line), fp)) {
- struct passwd *pw;
-
- if ((pw = userdb__buildUser(line)) != 0) {
- D( userdb__dumpUser(pw, stdout); )
- if (userdb__byName(&userdb__users, pw->pw_name))
- userdb_freeUser(pw);
- else
- userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid, pw);
- }
- }
- pclose(fp);
- }
-
- /* --- Next, groups --- */
-
-
- if ((fp = popen("ypcat group", "r")) != 0) {
- while (userdb__getLine(line, sizeof(line), fp)) {
- struct group *gr;
-
- if ((gr = userdb__buildGroup(line)) != 0) {
- D( userdb__dumpGroup(gr, stdout); )
- if (userdb__byName(&userdb__groups, gr->gr_name))
- userdb_freeGroup(gr);
- else
- userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid, gr);
- }
- }
- pclose(fp);
- }
-
-#endif
-
-}
+/*----- Answering queries -------------------------------------------------*/
/* --- @userdb_userByName@, @userdb_userById@ --- *
*
return (s ? s->rec : 0);
}
+/*----- Yellow pages support ----------------------------------------------*/
+
+#ifdef HAVE_YP
+
+/* --- @userdb__foreachUser@ --- *
+ *
+ * Arguments: @int st@ = YP protocol-level status code
+ * @char *k@ = address of the key for this record
+ * @int ksz@ = size of the key
+ * @char *v@ = address of the value for this record
+ * @int vsz@ = size of the value
+ * @char *data@ = pointer to some data passed to me
+ *
+ * Returns: Zero to be called again, nonzero to end the enumeration.
+ *
+ * Use: Handles an incoming user record.
+ */
+
+static int userdb__foreachUser(int st, char *k, int ksz,
+ char *v, int vsz, char *data)
+{
+ char *cv;
+ struct passwd *pw;
+
+ if (st != YP_TRUE)
+ return (-1);
+ cv = xmalloc(vsz + 1);
+ memcpy(cv, v, vsz);
+ cv[vsz] = 0;
+ pw = userdb__buildUser(cv);
+ if (pw && !userdb__byName(&userdb__users, pw->pw_name))
+ userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid, pw);
+ free(cv);
+ return (0);
+}
+
+/* --- @userdb__foreachGroup@ --- *
+ *
+ * Arguments: @int st@ = YP protocol-level status code
+ * @char *k@ = address of the key for this record
+ * @int ksz@ = size of the key
+ * @char *v@ = address of the value for this record
+ * @int vsz@ = size of the value
+ * @char *data@ = pointer to some data passed to me
+ *
+ * Returns: Zero to be called again, nonzero to end the enumeration.
+ *
+ * Use: Handles an incoming user record.
+ */
+
+static int userdb__foreachGroup(int st, char *k, int ksz,
+ char *v, int vsz, char *data)
+{
+ char *cv;
+ struct group *gr;
+
+ if (st != YP_TRUE)
+ return (-1);
+ cv = xmalloc(vsz + 1);
+ memcpy(cv, v, vsz);
+ cv[vsz] = 0;
+ gr = userdb__buildGroup(cv);
+ if (gr && !userdb__byName(&userdb__groups, gr->gr_name))
+ userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid, gr);
+ free(cv);
+ return (0);
+}
+
+/* --- @userdb_yp@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Fetches the YP database of users.
+ */
+
+void userdb_yp(void)
+{
+ char *ypdom;
+
+ /* --- Bind to a server --- */
+
+ if (yp_get_default_domain(&ypdom) ||
+ yp_bind(ypdom))
+ return;
+
+ /* --- Fetch the users map --- */
+
+ {
+ static struct ypall_callback ucb = { userdb__foreachUser, 0 };
+ yp_all(ypdom, "passwd.byuid", &ucb);
+ }
+
+ /* --- Fetch the groups map --- */
+
+ {
+ static struct ypall_callback gcb = { userdb__foreachGroup, 0 };
+ yp_all(ypdom, "group.bygid", &gcb);
+ }
+
+ yp_unbind(ypdom);
+ free(ypdom);
+}
+
+#else
+
+void userdb_yp(void) { ; }
+
+#endif
+
+/*----- Building the databases --------------------------------------------*/
+
+/* --- @userdb_local@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Reads the local list of users into the maps.
+ */
+
+void userdb_local(void)
+{
+ D( printf("adding local users...\n"); )
+
+ /* --- Fetch users first --- */
+
+ {
+ struct passwd *pw;
+
+ setpwent();
+ while ((pw = getpwent()) != 0) {
+ D( userdb__dumpUser(pw, stdout); )
+ if (!userdb__byName(&userdb__users, pw->pw_name))
+ userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid,
+ userdb_copyUser(pw));
+ }
+ endpwent();
+ }
+
+ /* --- Then fetch groups --- */
+
+ {
+ struct group *gr;
+
+ setgrent();
+ while ((gr = getgrent()) != 0) {
+ D( userdb__dumpGroup(gr, stdout); )
+ if (!userdb__byName(&userdb__groups, gr->gr_name))
+ userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid,
+ userdb_copyGroup(gr));
+ }
+ endgrent();
+ }
+}
+
/* --- @userdb_init@ --- *
*
* Arguments: ---
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: userdb.h,v $
- * Revision 1.1 1997/07/21 13:47:42 mdw
+ * Revision 1.2 1997/08/04 10:24:26 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:42 mdw
* Initial revision
*
*/
/* -*-c-*-
*
- * $Id: utils.c,v 1.1 1997/07/21 13:47:42 mdw Exp $
+ * $Id: utils.c,v 1.2 1997/08/04 10:24:26 mdw Exp $
*
* Miscellaneous useful bits of code.
*
* (c) 1997 Mark Wooding
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: utils.c,v $
- * Revision 1.1 1997/07/21 13:47:42 mdw
+ * Revision 1.2 1997/08/04 10:24:26 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:42 mdw
* Initial revision
*
*/
/* --- ANSI headers --- */
+#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
/* --- Local headers --- */
#include "config.h"
#include "utils.h"
-/*----- Static data -------------------------------------------------------*/
+/*----- Program name handling ---------------------------------------------*/
-static const char *myname = 0; /* What's my name? */
+/* --- Static data --- */
-/*----- Program name handling ---------------------------------------------*/
+static const char *myname = 0; /* What's my name? */
/* --- @quis@ --- *
*
exit(EXIT_FAILURE);
}
+/*----- Trace messages ----------------------------------------------------*/
+
+#if defined(TRACING) || !defined(NDEBUG)
+
+/* --- Static data --- */
+
+static FILE *tracefp = 0; /* Where does debugging go? */
+static unsigned int tracelvl = 0; /* How much tracing gets done? */
+
+/* --- @trace@ --- *
+ *
+ * Arguments: @unsigned int lvl@ = trace level for output
+ * @const char *f@ = a @printf@-style format string
+ * @...@ = other arguments
+ *
+ * Returns: ---
+ *
+ * Use: Reports a message to the trace output.
+ */
+
+void trace(unsigned int lvl, const char *f, ...)
+{
+ va_list ap;
+ if ((lvl & tracing()) == 0)
+ return;
+ va_start(ap, f);
+ fprintf(tracefp, "*** %s: ", myname);
+ vfprintf(tracefp, f, ap);
+ va_end(ap);
+ putc('\n', tracefp);
+}
+
+/* --- @traceblk@ --- *
+ *
+ * Arguments: @unsigned int lvl@ = trace level for output
+ * @const char *hdr@ = some header string to write
+ * @const void *blk@ = pointer to a block of memory to dump
+ * @size_t sz@ = size of the block of memory
+ *
+ * Returns: ---
+ *
+ * Use: Dumps the contents of a block to the trace output.
+ */
+
+void traceblk(unsigned int lvl, const char *hdr, const void *blk, size_t sz)
+{
+ const unsigned char *p = blk;
+ size_t i;
+ unsigned long o = 0;
+ size_t c;
+
+ /* --- Skip if the trace level is too high --- */
+
+ if ((lvl & tracing()) == 0)
+ return;
+
+ /* --- Now start work --- */
+
+ fprintf(tracefp, "*** %s: %s\n", myname, hdr);
+
+ while (sz) {
+ fprintf(tracefp, "*** %s: %08lu : ", myname, o);
+ for (i = 0; i < 8; i++) {
+ if (i < sz)
+ fprintf(tracefp, "%02x ", p[i]);
+ else
+ fputs("** ", tracefp);
+ }
+ fputs(": ", tracefp);
+ for (i = 0; i < 8; i++) {
+ if (i < sz)
+ fputc(isprint(p[i]) ? p[i] : '.', tracefp);
+ else
+ fputc('*', tracefp);
+ }
+ fputc('\n', tracefp);
+ c = (sz >= 8) ? 8 : sz;
+ sz -= c, p += c, o += c;
+ }
+}
+
+
+/* --- @traceon@ --- *
+ *
+ * Arguments: @FILE *fp@ = a file to trace on
+ * @unsigned int lvl@ = trace level to set
+ *
+ * Returns: ---
+ *
+ * Use: Enables tracing to a file.
+ */
+
+void traceon(FILE *fp, unsigned int lvl)
+{
+ tracefp = fp;
+ if (!tracelvl)
+ tracelvl = lvl;
+}
+
+/* --- @tracesetlvl@ --- *
+ *
+ * Arguments: @unsigned int lvl@ = trace level to set
+ *
+ * Returns: ---
+ *
+ * Use: Sets the tracing level.
+ */
+
+void tracesetlvl(unsigned int lvl) { tracelvl = lvl; }
+
+/* --- @tracing@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: Zero if not tracing, tracing level if tracing.
+ *
+ * Use: Informs the caller whether tracing is enabled.
+ */
+
+unsigned int tracing(void) { return (tracefp ? tracelvl : 0u); }
+
+#endif
+
/*----- Memory management functions ---------------------------------------*/
/* --- @xmalloc@ --- *
/* -*-c-*-
*
- * $Id: utils.h,v 1.1 1997/07/21 13:47:42 mdw Exp $
+ * $Id: utils.h,v 1.2 1997/08/04 10:24:26 mdw Exp $
*
* Miscellaneous useful bits of code.
*
* (c) 1997 Mark Wooding
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: utils.h,v $
- * Revision 1.1 1997/07/21 13:47:42 mdw
+ * Revision 1.2 1997/08/04 10:24:26 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:42 mdw
* Initial revision
*
*/
(p)[2] = ((unsigned long)(v) >> 16) & 0xFF, \
(p)[3] = ((unsigned long)(v) >> 24) & 0xFF)
+/*----- Other macros ------------------------------------------------------*/
+
+/* --- @burn@ --- *
+ *
+ * Arguments: @obj@ = some object
+ *
+ * Use: Writes zero bytes over the object.
+ */
+
+#define burn(obj) ((void)memset(&obj, 0, sizeof(obj)))
+
/*----- Program name handling ---------------------------------------------*/
/* --- @quis@ --- *
extern void die(const char */*f*/, ...);
+/*----- Trace messages ----------------------------------------------------*/
+
+#if !defined(NDEBUG) && !defined(TRACING)
+# define TRACING
+#endif
+
+#ifdef TRACING
+
+/* --- @trace@ --- *
+ *
+ * Arguments: @unsigned int lvl@ = trace level for output
+ * @const char *f@ = a @printf@-style format string
+ * @...@ = other arguments
+ *
+ * Returns: ---
+ *
+ * Use: Reports a message to the trace output.
+ */
+
+extern void trace(unsigned int /*lvl*/, const char */*f*/, ...);
+
+/* --- @traceblk@ --- *
+ *
+ * Arguments: @unsigned int lvl@ = trace level for output
+ * @const char *hdr@ = some header string to write
+ * @const void *blk@ = pointer to a block of memory to dump
+ * @size_t sz@ = size of the block of memory
+ *
+ * Returns: ---
+ *
+ * Use: Dumps the contents of a block to the trace output.
+ */
+
+extern void traceblk(unsigned int /*lvl*/, const char */*hdr*/,
+ const void */*blk*/, size_t /*sz*/);
+
+/* --- @traceon@ --- *
+ *
+ * Arguments: @FILE *fp@ = a file to trace on
+ * @unsigned int lvl@ = trace level to set
+ *
+ * Returns: ---
+ *
+ * Use: Enables tracing to a file.
+ */
+
+extern void traceon(FILE */*fp*/, unsigned int /*lvl*/);
+
+/* --- @tracesetlvl@ --- *
+ *
+ * Arguments: @unsigned int lvl@ = trace level to set
+ *
+ * Returns: ---
+ *
+ * Use: Sets the tracing level.
+ */
+
+extern void tracesetlvl(unsigned int /*lvl*/);
+
+/* --- @tracing@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: Zero if not tracing, tracing level if tracing.
+ *
+ * Use: Informs the caller whether tracing is enabled.
+ */
+
+extern unsigned int tracing(void);
+
+#endif
+
+/* --- Some hacky macros --- */
+
+#ifdef TRACING
+# define T(x) x
+# define IF_TRACING(lvl, x) if ((lvl) & tracing()) x
+#else
+# define T(x)
+# define IF_TRACING(lvl, x)
+#endif
+
/*----- Memory management functions ---------------------------------------*/
/* --- @xmalloc@ --- *