From 03f996bd8a0d6391518979cdab3dbe38cba0bf83 Mon Sep 17 00:00:00 2001 From: mdw Date: Mon, 4 Aug 1997 10:24:26 +0000 Subject: [PATCH] Sources placed under CVS control. --- acconfig.h | 4 +- aclocal.m4 | 4 +- configure.in | 58 ++++--- manual/become.tex | 9 +- mkinstalldirs | 2 +- src/Makefile.am | 4 +- src/become.c | 401 ++++++++++++++++++++++++++++++++++++++-------- src/blowfish-sbox.h | 7 +- src/blowfish.c | 7 +- src/blowfish.h | 7 +- src/check.c | 450 ++++++++++++++++++++++++++++++++++++++++------------ src/check.h | 13 +- src/class.c | 105 ++++++------ src/class.h | 16 +- src/crypt.c | 276 ++++++++++++-------------------- src/crypt.h | 24 +-- src/daemon.c | 56 +++++-- src/daemon.h | 13 +- src/dbutils.h | 7 +- src/icrypt.c | 18 ++- src/icrypt.h | 13 +- src/idea.c | 14 +- src/idea.h | 13 +- src/keygen.c | 19 ++- src/lexer.h | 13 +- src/lexer.l | 13 +- src/md5.c | 13 +- src/md5.h | 13 +- src/mdwopt.c | 17 +- src/mdwopt.h | 15 +- src/name.c | 162 ++++++++++++------- src/name.h | 17 +- src/parser.h | 13 +- src/parser.y | 13 +- src/rule.c | 91 +++++++++-- src/rule.h | 24 ++- src/set.c | 13 +- src/set.h | 13 +- src/sym.c | 34 +++- src/sym.h | 13 +- src/tx.c | 13 +- src/tx.h | 13 +- src/userdb.c | 310 ++++++++++++++++++++---------------- src/userdb.h | 11 +- src/utils.c | 144 ++++++++++++++++- src/utils.h | 106 ++++++++++++- 46 files changed, 1783 insertions(+), 831 deletions(-) diff --git a/acconfig.h b/acconfig.h index d108f96..6cb2ced 100644 --- a/acconfig.h +++ b/acconfig.h @@ -1,6 +1,6 @@ /* -*-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 * @@ -29,7 +29,7 @@ /*----- 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 diff --git a/aclocal.m4 b/aclocal.m4 index 16a9ca8..ae47bf2 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ 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 @@ -28,7 +28,7 @@ dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 diff --git a/configure.in b/configure.in index 7dc5995..9bbf801 100644 --- a/configure.in +++ b/configure.in @@ -1,13 +1,13 @@ 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 @@ -22,20 +22,25 @@ dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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 --- @@ -45,54 +50,59 @@ AC_PROG_LEX 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" diff --git a/manual/become.tex b/manual/become.tex index b3cc061..16785b5 100644 --- a/manual/become.tex +++ b/manual/become.tex @@ -1,6 +1,6 @@ %%% -*-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' %%% @@ -28,9 +28,12 @@ %%%----- 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 -------------------------------------------------- diff --git a/mkinstalldirs b/mkinstalldirs index d41f6c0..57a53d5 100755 --- a/mkinstalldirs +++ b/mkinstalldirs @@ -4,7 +4,7 @@ # 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 diff --git a/src/Makefile.am b/src/Makefile.am index 88434ec..af41625 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ ## 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' ## @@ -29,7 +29,7 @@ ##----- 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. ## diff --git a/src/become.c b/src/become.c index c2d8bcf..627eda5 100644 --- a/src/become.c +++ b/src/become.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -43,6 +46,7 @@ #include #include #include +#include /* --- Unix headers --- */ @@ -60,6 +64,8 @@ #include #include +extern char **environ; + /* --- Local headers --- */ #include "become.h" @@ -72,6 +78,7 @@ #include "parser.h" #include "rule.h" #include "utils.h" +#include "userdb.h" /*----- Main code ---------------------------------------------------------*/ @@ -143,6 +150,24 @@ static void bc__usage(FILE *fp) " $ -d [-p ] [-f ]\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 @@ -174,11 +199,17 @@ static void bc__help(FILE *fp) "\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@ --- * @@ -193,45 +224,89 @@ static void bc__help(FILE *fp) 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); @@ -240,6 +315,12 @@ int main(int argc, char *argv[]) bc__banner(stdout); exit(0); break; + + /* --- Various simple options --- */ + + case 'l': + flags |= f_login; + break; case 'c': cmd = optarg; break; @@ -252,12 +333,143 @@ int main(int argc, char *argv[]) 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; @@ -271,6 +483,7 @@ int main(int argc, char *argv[]) /* --- Switch to daemon mode if requested --- */ if (flags & f_daemon) { + T( trace(TRACE_MISC, "become: daemon mode requested"); ) daemon_init(conffile, port); exit(0); } @@ -284,22 +497,34 @@ int main(int argc, char *argv[]) { 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 --- */ @@ -312,46 +537,89 @@ int main(int argc, char *argv[]) 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; @@ -359,9 +627,10 @@ int main(int argc, char *argv[]) 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 --- */ @@ -373,7 +642,7 @@ int main(int argc, char *argv[]) /* --- 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)); @@ -392,7 +661,7 @@ int main(int argc, char *argv[]) */ 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 --- */ @@ -437,27 +706,17 @@ int main(int argc, char *argv[]) *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"); @@ -465,16 +724,18 @@ int main(int argc, char *argv[]) /* --- 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 -------------------------------------------------*/ diff --git a/src/blowfish-sbox.h b/src/blowfish-sbox.h index 0baf11c..42099b3 100644 --- a/src/blowfish-sbox.h +++ b/src/blowfish-sbox.h @@ -1,6 +1,6 @@ /* -*-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 * @@ -29,7 +29,10 @@ /*----- 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 * */ diff --git a/src/blowfish.c b/src/blowfish.c index ddf7b26..8cc302d 100644 --- a/src/blowfish.c +++ b/src/blowfish.c @@ -1,6 +1,6 @@ /* -*-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 * @@ -29,7 +29,10 @@ /*----- 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 * */ diff --git a/src/blowfish.h b/src/blowfish.h index 23519a6..46eb0ef 100644 --- a/src/blowfish.h +++ b/src/blowfish.h @@ -1,6 +1,6 @@ /* -*-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 * @@ -29,7 +29,10 @@ /*----- 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 * */ diff --git a/src/check.c b/src/check.c index 9ed0b6f..1d1eba8 100644 --- a/src/check.c +++ b/src/check.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -69,114 +72,160 @@ #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 --- */ @@ -186,8 +235,8 @@ static int check__client(request *rq, const char *serv, int port) /* --- 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)); @@ -205,26 +254,245 @@ static int check__client(request *rq, const char *serv, int port) (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{ [`:' ]}%% + * + * 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 @@ -240,41 +508,19 @@ int check(request *rq) /* --- 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); diff --git a/src/check.h b/src/check.h index 24f5cb9..53b4c6b 100644 --- a/src/check.h +++ b/src/check.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/class.c b/src/class.c index d2f5e4b..7a7d016 100644 --- a/src/class.c +++ b/src/class.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -55,6 +58,7 @@ /* --- Local headers --- */ +#include "become.h" #include "class.h" #include "set.h" #include "sym.h" @@ -166,10 +170,16 @@ int class_userMatch(classdef *c, int u) { 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@ --- * @@ -192,13 +202,18 @@ int class_commandMatch(classdef *c, const char *p) 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); } } @@ -224,16 +239,22 @@ int class_hostMatch(classdef *c, struct in_addr addr) 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 --- * * @@ -244,21 +265,33 @@ int class_hostMatch(classdef *c, struct in_addr addr) /* --- 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); } } @@ -266,60 +299,34 @@ int class_hostMatch(classdef *c, struct in_addr addr) /* --- @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 -------------------------------------------------*/ diff --git a/src/class.h b/src/class.h index cbe3929..9abbe3f 100644 --- a/src/class.h +++ b/src/class.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -156,14 +159,13 @@ extern int class_hostMatch(classdef */*c*/, struct in_addr /*addr*/); /* --- @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 -------------------------------------------------*/ diff --git a/src/crypt.c b/src/crypt.c index 86ed605..d052471 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -48,73 +51,27 @@ /* --- Unix headers --- */ #include +#include #include #include #include /* --- 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 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@ --- * @@ -265,6 +177,11 @@ void crypt_packRequest(request *rq, unsigned char *buff, 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 @@ -282,45 +199,39 @@ void crypt_packRequest(request *rq, unsigned char *buff, 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 --- * @@ -334,7 +245,8 @@ void crypt_packRequest(request *rq, unsigned char *buff, { 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); @@ -343,7 +255,8 @@ void crypt_packRequest(request *rq, unsigned char *buff, 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); ) } } @@ -376,7 +289,8 @@ int crypt_unpackRequest(request *rq, unsigned char *buff, 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); @@ -389,23 +303,25 @@ int crypt_unpackRequest(request *rq, unsigned char *buff, 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); } { @@ -424,6 +340,7 @@ int crypt_unpackRequest(request *rq, unsigned char *buff, 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); @@ -431,6 +348,7 @@ int crypt_unpackRequest(request *rq, unsigned char *buff, /* --- Done --- */ + T( trace(TRACE_CRYPTO, "crypto: valid request received"); ) return (1); } @@ -457,25 +375,28 @@ void crypt_packReply(unsigned char *buff, unsigned char *sk, int answer) /* --- 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); ) } } @@ -498,28 +419,32 @@ int crypt_unpackReply(unsigned char *buff, unsigned char *sk, /* --- 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); } @@ -528,12 +453,14 @@ int crypt_unpackReply(unsigned char *buff, unsigned char *sk, 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]); } @@ -543,13 +470,12 @@ int crypt_unpackReply(unsigned char *buff, unsigned char *sk, 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"); @@ -557,7 +483,7 @@ int main(int argc, char *argv[]) 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); } diff --git a/src/crypt.h b/src/crypt.h index b508b45..e84f508 100644 --- a/src/crypt.h +++ b/src/crypt.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -93,17 +96,6 @@ enum { 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@ --- * diff --git a/src/daemon.c b/src/daemon.c index eb36b39..3f1fa93 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -152,6 +155,7 @@ static int daemon__readConfig(const char *cf) if (!daemon__readKey) daemon_readKey(file_KEY); daemon__rescan = 0; + T( trace(TRACE_DAEMON, "daemon: read config file"); ) return (0); } @@ -210,6 +214,8 @@ void daemon__read(int fd) 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; } @@ -226,12 +232,14 @@ void daemon__read(int fd) 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; } @@ -254,6 +262,7 @@ void daemon__read(int fd) /* --- 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); } @@ -345,26 +354,38 @@ void daemon_init(const char *cf, int port) 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 --- * * @@ -391,6 +412,7 @@ void daemon_init(const char *cf, int port) /* --- 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 --- */ diff --git a/src/daemon.h b/src/daemon.h index ed3c05c..a1b1eef 100644 --- a/src/daemon.h +++ b/src/daemon.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/dbutils.h b/src/dbutils.h index 70f24ee..89dff81 100644 --- a/src/dbutils.h +++ b/src/dbutils.h @@ -1,6 +1,6 @@ /* -*-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 * @@ -29,7 +29,10 @@ /*----- 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 * */ diff --git a/src/icrypt.c b/src/icrypt.c index 828ce1e..589c5a5 100644 --- a/src/icrypt.c +++ b/src/icrypt.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -285,12 +288,13 @@ int main(int argc, char *argv[]) { 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) diff --git a/src/icrypt.h b/src/icrypt.h index 38deed9..2117814 100644 --- a/src/icrypt.h +++ b/src/icrypt.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/idea.c b/src/idea.c index e1bacfe..1bdd9e8 100644 --- a/src/idea.c +++ b/src/idea.c @@ -1,6 +1,6 @@ /* -*-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 @@ -8,7 +8,7 @@ * (c) 1996, 1997 Mark Wooding */ -/*----- Licencing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of `become' * @@ -23,14 +23,17 @@ * 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 * */ @@ -48,6 +51,7 @@ /*----- Header files ------------------------------------------------------*/ #include +#include #include "config.h" #include "idea.h" diff --git a/src/idea.h b/src/idea.h index 79ca601..08e7f93 100644 --- a/src/idea.h +++ b/src/idea.h @@ -1,6 +1,6 @@ /* -*-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 @@ -8,7 +8,7 @@ * (c) 1996, 1997 Mark Wooding */ -/*----- Licencing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of `become' * @@ -23,14 +23,17 @@ * 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 * */ diff --git a/src/keygen.c b/src/keygen.c index 17bf93c..f1b0abe 100644 --- a/src/keygen.c +++ b/src/keygen.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -245,9 +248,9 @@ static void kg__gen(unsigned char *ui, size_t sz) 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; @@ -261,7 +264,7 @@ static void kg__gen(unsigned char *ui, size_t sz) /* --- Print current status --- */ - fprintf(kg__ttyfp, "\r%5i...", sz); + fprintf(kg__ttyfp, "\r%5lu...", (unsigned long)sz); fflush(kg__ttyfp); /* --- Read the next character --- */ diff --git a/src/lexer.h b/src/lexer.h index 603d382..c3bbc65 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/lexer.l b/src/lexer.l index 597690a..ccaff7e 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/md5.c b/src/md5.c index 80cadf2..23ce693 100644 --- a/src/md5.c +++ b/src/md5.c @@ -1,6 +1,6 @@ /* -*-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 @@ -8,7 +8,7 @@ * (c) 1996, 1997 Mark Wooding */ -/*----- Licencing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of `become' * @@ -23,14 +23,17 @@ * 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 * */ diff --git a/src/md5.h b/src/md5.h index a105630..bce4d47 100644 --- a/src/md5.h +++ b/src/md5.h @@ -1,6 +1,6 @@ /* -*-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 @@ -8,7 +8,7 @@ * (c) 1996, 1997 Mark Wooding */ -/*----- Licencing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of `become' * @@ -23,14 +23,17 @@ * 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 * */ diff --git a/src/mdwopt.c b/src/mdwopt.c index af30491..ad078a5 100644 --- a/src/mdwopt.c +++ b/src/mdwopt.c @@ -1,6 +1,6 @@ /* -*-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@ * @@ -22,15 +22,20 @@ * 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. @@ -57,7 +62,7 @@ #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 '/' diff --git a/src/mdwopt.h b/src/mdwopt.h index 38e89e4..78087d6 100644 --- a/src/mdwopt.h +++ b/src/mdwopt.h @@ -1,6 +1,6 @@ /* -*-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@ * @@ -22,19 +22,18 @@ * 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. diff --git a/src/name.c b/src/name.c index faa06ab..fe61272 100644 --- a/src/name.c +++ b/src/name.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -44,11 +47,19 @@ /* --- Unix headers --- */ +#include "config.h" + +#ifdef HAVE_YP +# include +# include +#endif + #include #include /* --- Local headers --- */ +#include "become.h" #include "class.h" #include "name.h" #include "sym.h" @@ -61,87 +72,113 @@ static sym_table name__table; /* Symbol table for everything */ /*----- 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 --- * * @@ -213,21 +250,22 @@ name *name_find(const char *p, unsigned create, unsigned *f) /* --- @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); } } @@ -240,8 +278,10 @@ int main(void) userdb_init(); userdb_local(); userdb_yp(); + ego("name-test"); + traceon(stdout, TRACE_DEBUG); name_init(); - name_dump(stdout); + name_dump(); return (0); } diff --git a/src/name.h b/src/name.h index 8d94ed5..93793c9 100644 --- a/src/name.h +++ b/src/name.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -105,14 +108,14 @@ extern name *name_find(const char */*p*/, /* --- @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 -------------------------------------------------*/ diff --git a/src/parser.h b/src/parser.h index cd64a67..db09482 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/parser.y b/src/parser.y index 0a8462f..688ffc4 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/rule.c b/src/rule.c index 000c290..41fa371 100644 --- a/src/rule.c +++ b/src/rule.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -42,11 +45,21 @@ #include #include +/* --- Unix headers --- */ + +#include +#include +#include +#include +#include +#include + /* --- Local headers --- */ #include "become.h" #include "class.h" #include "rule.h" +#include "userdb.h" #include "utils.h" /*----- Type definitions --------------------------------------------------*/ @@ -142,17 +155,77 @@ void rule_add(classdef *host, classdef *from, classdef *to, classdef *cmd) 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 : "", (long)r->from, + pw_to ? pw_to->pw_name : "", (long)r->to); + trace(TRACE_CHECK, "check: ... at %s (%s) for `%s'", + h ? h->h_name : "", 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 -------------------------------------------------*/ diff --git a/src/rule.h b/src/rule.h index 7e337f6..8ce7ea2 100644 --- a/src/rule.h +++ b/src/rule.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -106,6 +109,17 @@ extern void rule_add(classdef */*host*/, classdef */*from*/, 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 diff --git a/src/set.c b/src/set.c index 7c36bb7..75a7a72 100644 --- a/src/set.c +++ b/src/set.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/set.h b/src/set.h index 62b15c5..2620426 100644 --- a/src/set.h +++ b/src/set.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/sym.c b/src/sym.c index d882f5f..a698382 100644 --- a/src/sym.c +++ b/src/sym.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -575,7 +578,10 @@ int main(void) 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]) @@ -590,7 +596,10 @@ int main(void) 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) @@ -618,6 +627,11 @@ int main(void) 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"); @@ -641,6 +655,7 @@ int main(void) case 3: { sym_base *b; int v = rand() & 255 ? 0 : 1; + break; printf("dump\n"); @@ -663,7 +678,10 @@ int main(void) 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--; diff --git a/src/sym.h b/src/sym.h index 8f708e1..16511af 100644 --- a/src/sym.h +++ b/src/sym.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/tx.c b/src/tx.c index b17456a..54a04f4 100644 --- a/src/tx.c +++ b/src/tx.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/tx.h b/src/tx.h index 4aaaaee..d5fef73 100644 --- a/src/tx.h +++ b/src/tx.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/userdb.c b/src/userdb.c index bcefc85..77e1a3d 100644 --- a/src/userdb.c +++ b/src/userdb.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -46,15 +49,21 @@ /* --- Unix headers --- */ +#include "config.h" + #include +#ifdef HAVE_YP +# include +# include +#endif + #include #include #include /* --- Local headers --- */ -#include "config.h" #include "sym.h" #include "userdb.h" #include "utils.h" @@ -486,137 +495,7 @@ void userdb_freeGroup(void *rec) 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@ --- * * @@ -716,6 +595,163 @@ struct group *userdb_nextGroup_r(userdb_iter *i) 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: --- diff --git a/src/userdb.h b/src/userdb.h index 91038d7..19dba5f 100644 --- a/src/userdb.h +++ b/src/userdb.h @@ -7,7 +7,7 @@ * (c) 1997 EBI */ -/*----- Licencing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of `become' * @@ -22,14 +22,17 @@ * 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 * */ diff --git a/src/utils.c b/src/utils.c index a46a310..7867411 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -38,20 +41,22 @@ /* --- ANSI headers --- */ +#include #include #include #include +#include /* --- 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@ --- * * @@ -140,6 +145,129 @@ void die(const char *f, ...) 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@ --- * diff --git a/src/utils.h b/src/utils.h index 09ee6d2..dce373e 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,13 +1,13 @@ /* -*-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' * @@ -22,14 +22,17 @@ * 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 * */ @@ -78,6 +81,17 @@ (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@ --- * @@ -129,6 +143,88 @@ extern void moan(const char */*f*/, ...); 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@ --- * -- 2.11.0