/* -*-c-*-
*
- * $Id: become.c,v 1.11 1997/09/24 09:48:45 mdw Exp $
+ * $Id: become.c,v 1.16 1998/04/23 13:21:04 mdw Exp $
*
* Main code for `become'
*
- * (c) 1997 EBI
+ * (c) 1998 EBI
*/
/*----- Licensing notice --------------------------------------------------*
/*----- Revision history --------------------------------------------------*
*
* $Log: become.c,v $
- * Revision 1.11 1997/09/24 09:48:45 mdw
+ * 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.
+ *
+ * Revision 1.12 1997/09/25 16:04:48 mdw
+ * Change directory after becoming someone else, instead of before. This
+ * avoids problems with root-squashed NFS mounts.
+ *
+ * Revision 1.11.2.1 1997/09/26 09:07:58 mdw
+ * Use the Blowfish encryption algorithm instead of IDEA. This is partly
+ * because I prefer Blowfish (without any particularly strong evidence) but
+ * mainly because IDEA is patented and Blowfish isn't.
+ *
+ * Revision 1.11 1997/09/24 09:48:45 mdw
* Fix (scary) overrun bug in group allocation stuff.
*
* Revision 1.10 1997/09/17 10:14:10 mdw
/* --- 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 --- */
enum {
f_daemon = 1, /* Start up in daemon mode */
f_duff = 2, /* Fault in arguments */
- f_login = 4, /* Execute as a login shell */
+ f_shell = 4, /* Run a default shell */
f_dummy = 8, /* Don't actually do anything */
f_setuid = 16, /* We're running setuid */
f_havegroup = 32 /* Set a default group */
/* --- 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 --- */
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)));
}
binary = todo[0];
}
- else switch (style) {
+ else {
+ flags |= f_shell;
- /* --- An unadorned becoming requires little work --- */
+ switch (style) {
- case l_preserve:
- shell[0] = getenv("SHELL");
- if (!shell[0])
- shell[0] = from_pw->pw_shell;
- shell[1] = 0;
- todo = shell;
- binary = todo[0];
- break;
+ /* --- An unadorned becoming requires little work --- */
- /* --- An su-like login needs slightly less effort --- */
+ case l_preserve:
+ shell[0] = getenv("SHELL");
+ if (!shell[0])
+ shell[0] = from_pw->pw_shell;
+ shell[1] = 0;
+ todo = shell;
+ binary = todo[0];
+ break;
- case l_setuser:
- shell[0] = to_pw->pw_shell;
- shell[1] = 0;
- todo = shell;
- binary = todo[0];
- break;
+ /* --- An su-like login needs slightly less effort --- */
+
+ case l_setuser:
+ shell[0] = to_pw->pw_shell;
+ shell[1] = 0;
+ todo = shell;
+ binary = todo[0];
+ break;
- /* --- A login request needs a little bit of work --- */
-
- case l_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;
- chdir(to_pw->pw_dir);
- } break;
+ /* --- A login request needs a little bit of work --- */
+
+ case l_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;
+ } break;
+ }
}
/* --- Mangle the environment --- *
*/
static char *preserve[] = {
- "TERM", "DISPLAY", 0
+ "TERM", "DISPLAY", "TZ", 0
};
/* --- Variables to be expunged --- *
if (rq.from == rq.to) {
moan("you already are `%s'!", to_pw->pw_name);
- if (!cmd && todo == shell) {
+ if (flags & f_shell) {
moan("(to prevent confusion, I'm not spawning a shell)");
exit(0);
}
if (setuid(rq.to) < 0)
die("couldn't set uid: %s", strerror(errno));
+ /* --- If this was a login, change current directory --- */
+
+ 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);