X-Git-Url: https://git.distorted.org.uk/~mdw/become/blobdiff_plain/9df0c75da76d81285c5fca90bb8d538c68b38119..7df38e1e83fd1fe5a9dee73bf8c346deb4e972f9:/src/become.c diff --git a/src/become.c b/src/become.c index d94e3c2..c5df906 100644 --- a/src/become.c +++ b/src/become.c @@ -1,10 +1,10 @@ /* -*-c-*- * - * $Id: become.c,v 1.10 1997/09/17 10:14:10 mdw Exp $ + * $Id: become.c,v 1.18 1998/06/26 10:32:54 mdw Exp $ * * Main code for `become' * - * (c) 1997 EBI + * (c) 1998 EBI */ /*----- Licensing notice --------------------------------------------------* @@ -29,7 +29,38 @@ /*----- Revision history --------------------------------------------------* * * $Log: become.c,v $ - * Revision 1.10 1997/09/17 10:14:10 mdw + * 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. + * + * 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 * Fix a typo. Support service names in `--port' option. * * Revision 1.9 1997/09/10 10:28:05 mdw @@ -131,11 +162,9 @@ enum { /* --- 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 --- * * @@ -304,8 +333,8 @@ static int bc__addGroups(gid_t *g, int *png, const gid_t *a, int na) /* --- See if there's room for more --- */ - if (ng > NGROUPS_MAX) { - moan("too many groups (system limit exceeded -- some have been lost"); + if (ng >= NGROUPS_MAX) { + moan("too many groups (system limit exceeded) -- some have been lost"); *png = ng; return (-1); } @@ -349,7 +378,10 @@ static void bc__usage(FILE *fp) "Usage: \n" " $ -c \n" " $ [] [ []...]\n" - " $ -d [-p ] [-f ]\n"); +#ifndef NONETWORK + " $ -d [-p ] [-f ]\n" +#endif + ); } /* --- @bc__help@ --- * @@ -389,7 +421,17 @@ static void bc__help(FILE *fp, int suid) "-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" @@ -398,10 +440,13 @@ static void bc__help(FILE *fp, int suid) #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) { @@ -439,8 +484,10 @@ int main(int argc, char *argv[]) /* --- 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 --- */ @@ -468,7 +515,7 @@ int main(int argc, char *argv[]) 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 */ @@ -525,9 +572,11 @@ int main(int argc, char *argv[]) /* --- Server options --- */ +#ifndef NONETWORK { "daemon", 0, 0, 'd' }, { "port", gFlag_argReq, 0, 'p' }, { "config-file", gFlag_argReq, 0, 'f' }, +#endif /* --- Tracing options --- */ @@ -550,7 +599,9 @@ int main(int argc, char *argv[]) "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 @@ -620,6 +671,7 @@ int main(int argc, char *argv[]) /* --- Server options --- */ +#ifndef NONETWORK case 'p': if (isdigit((unsigned char)optarg[0])) port = htons(atoi(optarg)); @@ -636,6 +688,7 @@ int main(int argc, char *argv[]) case 'f': conffile = optarg; break; +#endif /* --- Pretend to be a different user --- * * @@ -728,12 +781,14 @@ int main(int argc, char *argv[]) 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" }, @@ -851,11 +906,13 @@ done_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 --- */ @@ -901,7 +958,7 @@ done_options: 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 --- */ @@ -1008,7 +1065,7 @@ done_options: 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))); } @@ -1043,45 +1100,48 @@ done_options: binary = todo[0]; } - else switch (style) { + else { + flags |= f_shell; + + switch (style) { - /* --- An unadorned becoming requires little work --- */ + /* --- An unadorned becoming requires little work --- */ - 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_preserve: + shell[0] = getenv("SHELL"); + if (!shell[0]) + shell[0] = from_pw->pw_shell; + shell[1] = 0; + todo = shell; + binary = todo[0]; + break; - /* --- An su-like login needs slightly less effort --- */ + /* --- 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; + 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 --- */ - /* --- 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; + 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 --- * @@ -1118,7 +1178,7 @@ done_options: */ static char *preserve[] = { - "TERM", "DISPLAY", 0 + "TERM", "DISPLAY", "TZ", 0 }; /* --- Variables to be expunged --- * @@ -1420,7 +1480,7 @@ done_options: 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); } @@ -1455,9 +1515,19 @@ done_options: 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); + closelog(); execve(rq.cmd, todo, env); die("couldn't exec `%s': %s", rq.cmd, strerror(errno)); return (127);