/* -*-c-*-
*
- * $Id: become.c,v 1.13 1997/09/26 09:14:57 mdw Exp $
+ * $Id: become.c,v 1.20 1999/05/04 16:17:11 mdw Exp $
*
* Main code for `become'
*
- * (c) 1997 EBI
+ * (c) 1998 EBI
*/
/*----- Licensing notice --------------------------------------------------*
/*----- Revision history --------------------------------------------------*
*
* $Log: become.c,v $
+ * Revision 1.20 1999/05/04 16:17:11 mdw
+ * Change to header file name for parser. See log for `parse.h' for
+ * details.
+ *
+ * Revision 1.19 1998/06/29 13:10:41 mdw
+ * Add some commentary regarding an issue in `sudo' which affects `become';
+ * I'm not fixing it yet because I don't think it's important.
+ *
+ * Fixed the PATH lookup code to use the right binary name: `binary' rather
+ * than `todo[0]'. The two only differ when `style' is `l_login', in which
+ * case `binary' has an initial `/' anyway, and the PATH lookup code is
+ * never invoked. The name is used in a buffer-overflow precheck, though,
+ * and auditing is easier if the naming is consistent.
+ *
+ * Revision 1.18 1998/06/26 10:32:54 mdw
+ * Cosmetic change: use sizeof(destination) in memcpy.
+ *
+ * Revision 1.17 1998/06/18 15:06:59 mdw
+ * Close log before execing program to avoid leaving a socket open.
+ *
+ * Revision 1.16 1998/04/23 13:21:04 mdw
+ * Small tweaks. Support no-network configuration option, and rearrange
+ * the help text a little.
+ *
+ * Revision 1.15 1998/01/13 11:10:44 mdw
+ * Add `TZ' to the list of variables to be preserved.
+ *
+ * Revision 1.14 1998/01/12 16:45:39 mdw
+ * Fix copyright date.
+ *
* Revision 1.13 1997/09/26 09:14:57 mdw
* Merged blowfish branch into trunk.
*
#include "lexer.h"
#include "mdwopt.h"
#include "name.h"
-#include "parser.h"
+#include "parse.h"
#include "rule.h"
#include "sym.h"
#include "utils.h"
/* --- Login behaviour types --- */
-enum {
- l_preserve, /* Preserve the environment */
- l_setuser, /* Update who I am */
- l_login /* Do a full login */
-};
+#define l_preserve 0 /* Preserve the environment */
+#define l_setuser 1 /* Update who I am */
+#define l_login 2 /* Do a full login */
/* --- Group behaviour types --- *
*
"Usage: \n"
" $ -c <shell-command> <user>\n"
" $ [<env-var>] <user> [<command> [<arguments>]...]\n"
- " $ -d [-p <port>] [-f <config-file>]\n");
+#ifndef NONETWORK
+ " $ -d [-p <port>] [-f <config-file>]\n"
+#endif
+ );
}
/* --- @bc__help@ --- *
"-e, --preserve-environment Try to preserve the current environment\n"
"-s, --su, --set-user Set environment variables to reflect USER\n"
"-l, --login Really log in as USER\n"
-"\n"
+" [Default is "
+#if DEFAULT_LOGIN_STYLE == l_preserve
+ "preserve-environment"
+#elif DEFAULT_LOGIN_STYLE == l_setuser
+ "set-user"
+#elif DEFAULT_LOGIN_STYLE == l_login
+ "login"
+#else
+ "poorly configured"
+#endif
+"]\n\n"
"-g GROUP, --group=GROUP Set primary group-id to be GROUP\n"
#ifdef HAVE_SETGROUPS
"-k, --keep-groups Keep your current set of groups\n"
#endif
"\n"
"-c CMD, --command=CMD Run the (Bourne) shell command CMD\n"
+#ifndef NONETWORK
"\n"
"-d, --daemon Start a daemon\n"
"-p PORT, --port=PORT In daemon mode, listen on PORT\n"
-"-f FILE, --config-file=FILE In daemon mode, read config from FILE\n");
+"-f FILE, --config-file=FILE In daemon mode, read config from FILE\n"
+#endif
+ );
#ifdef TRACING
bc__write(fp, "\n");
if (!suid) {
/* --- Become server setup parameters --- */
+#ifndef NONETWORK
char *conffile = file_RULES; /* Default config file for daemon */
int port = 0; /* Default port for daemon */
+#endif
/* --- Miscellanous shared variables --- */
/* --- Server options --- */
+#ifndef NONETWORK
{ "daemon", 0, 0, 'd' },
{ "port", gFlag_argReq, 0, 'p' },
{ "config-file", gFlag_argReq, 0, 'f' },
+#endif
/* --- Tracing options --- */
"g:" /* Group (without @setgroups@) */
#endif
"c:" /* Command to run options */
+#ifndef NONETWORK
"dp:f:" /* Server options */
+#endif
#ifdef TRACING
"I:T::L::" /* Tracing options */
#endif
/* --- Server options --- */
+#ifndef NONETWORK
case 'p':
if (isdigit((unsigned char)optarg[0]))
port = htons(atoi(optarg));
case 'f':
conffile = optarg;
break;
+#endif
/* --- Pretend to be a different user --- *
*
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" },
+#ifndef NONETWORK
+ { 'd', TRACE_DAEMON, "server process" },
{ 'l', TRACE_CLIENT, "client process" },
{ 'R', TRACE_RAND, "random number generator" },
{ 'C', TRACE_CRYPTO, "cryptographic processing of requests" },
+#endif
{ 'y', TRACE_YACC, "parsing configuration file" },
{ 'D', TRACE_DFL, "default tracing options" },
{ 'A', TRACE_ALL, "all tracing options" },
/* --- Switch to daemon mode if requested --- */
+#ifndef NONETWORK
if (flags & f_daemon) {
T( trace(TRACE_MISC, "become: daemon mode requested"); )
daemon_init(conffile, port);
exit(0);
}
+#endif
/* --- Open a syslog --- */
uname(&u);
if ((he = gethostbyname(u.nodename)) == 0)
die("who am I? (can't resolve `%s')", u.nodename);
- memcpy(&rq.host, he->h_addr, sizeof(struct in_addr));
+ memcpy(&rq.host, he->h_addr, sizeof(rq.host));
}
/* --- Fiddle with group ownerships a bit --- */
ngroups = 0;
(void)(bc__addGroups(groups, &ngroups, ga, i) ||
((gstyle & g_keep) &&
- bc__addGroups(groups, &ngroups, from_gr,n_fgr)) ||
+ bc__addGroups(groups, &ngroups, from_gr, n_fgr)) ||
((gstyle & g_replace) &&
bc__addGroups(groups, &ngroups, to_gr, n_tgr)));
}
*/
static char *preserve[] = {
- "TERM", "DISPLAY", 0
+ "TERM", "DISPLAY", "TZ", 0
};
/* --- Variables to be expunged --- *
if (strlen(p) + strlen(binary) + 2 > sizeof(rq.cmd))
continue;
- /* --- Now build the pathname and check it --- */
+ /* --- Now build the pathname and check it --- *
+ *
+ * Issue: user can take advantage of these privileges to decide whether
+ * a program with a given name exists. I'm not sure that's
+ * particularly significant: it only works on regular files with
+ * execute permissions, and if you're relying on the names of these
+ * being secret to keep your security up, then you're doing something
+ * deeply wrong anyway. On the other hand, it's useful to allow people
+ * to be able to execute programs and scripts which they wouldn't
+ * otherwise have access to. [This problem was brought up on
+ * Bugtraq, as a complaint against sudo.]
+ */
- sprintf(rq.cmd, "%s/%s", p, todo[0]);
+ sprintf(rq.cmd, "%s/%s", p, binary);
if (stat(rq.cmd, &st) == 0 && /* Check it exists */
st.st_mode & 0111 && /* Check it's executable */
S_ISREG(st.st_mode)) /* Check it's a file */
/* --- If this was a login, change current directory --- */
- if (flags & f_shell && style == l_login && chdir(to_pw->pw_dir) < 0) {
+ if ((flags & f_shell) &&
+ style == l_login &&
+ chdir(to_pw->pw_dir) < 0) {
moan("couldn't change directory to `%s': %s",
to_pw->pw_dir, strerror(errno));
}
/* --- Finally, call the program --- */
fflush(0);
+ closelog();
execve(rq.cmd, todo, env);
die("couldn't exec `%s': %s", rq.cmd, strerror(errno));
return (127);