/* -*-c-*-
*
- * $Id: become.c,v 1.5 1997/09/05 11:45:19 mdw Exp $
+ * $Id: become.c,v 1.8 1997/09/08 13:56:24 mdw Exp $
*
* Main code for `become'
*
/*----- Revision history --------------------------------------------------*
*
* $Log: become.c,v $
- * Revision 1.5 1997/09/05 11:45:19 mdw
+ * Revision 1.8 1997/09/08 13:56:24 mdw
+ * Change criteria for expunging items from the user's PATH: instead of
+ * removing things starting with `.', remove things not starting with `/'.
+ *
+ * Revision 1.7 1997/09/08 13:43:20 mdw
+ * Change userid when creating tracefiles rather than fiddling with
+ * `access': it works rather better. Also, insert some stdio buffer
+ * flushing to ensure tracedumps are completely written.
+ *
+ * Revision 1.6 1997/09/05 13:47:44 mdw
+ * Make the `-L' (trace-level) option's argument optional, like the long
+ * version is.
+ *
+ * Revision 1.5 1997/09/05 11:45:19 mdw
* Add support for different login styles, and environment variable
* manipulation in a safe and useful way.
*
};
i = mdwopt(argc, argv,
- "-" "huv" "esl" "c:" "dp:f:" T("I:T::L:"),
+ "-" "huv" "esl" "c:" "dp:f:" T("I:T::L::"),
opts, 0, 0, gFlag_envVar);
if (i < 0)
goto done_options;
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));
+ uid_t eu = geteuid(), ru = getuid();
+
+#ifdef HAVE_SETREUID
+ if (setreuid(eu, ru))
+#else
+ if (seteuid(ru))
+#endif
+ {
+ die("couldn't temporarily give up privileges: %s",
+ strerror(errno));
}
+
if ((fp = fopen(optarg, "w")) == 0) {
die("couldn't open trace file `%s' for writing: %s",
optarg, strerror(errno));
}
+
+#ifdef HAVE_SETREUID
+ if (setreuid(ru, eu))
+#else
+ if (seteuid(eu))
+#endif
+ die("couldn't regain privileges: %s", strerror(errno));
}
traceon(fp, TRACE_DFL);
trace(TRACE_MISC, "become: tracing enabled");
static char *preserve[] = {
"TERM", "DISPLAY", 0
};
-
+
/* --- Variables to be expunged --- *
*
- * Any environment string which has one of the following as a prefix
- * will be expunged from the environment passed to the called process.
- * The first line lists variables which have been used to list search
- * paths for shared libraries: by manipulating these, an attacker could
- * replace a standard library with one of his own. The second line lists
- * other well-known dangerous environment variables.
+ * Any environment string which has one of the following as a prefix will
+ * be expunged from the environment passed to the called process. The
+ * first line lists variables which have been used to list search paths
+ * for shared libraries: by manipulating these, an attacker could replace
+ * a standard library with one of his own. The second line lists other
+ * well-known dangerous environment variables.
*/
static char *banned[] = {
size_t sz;
unsigned f;
sym_iter i;
-
+
/* --- Stage one. Preserve display-specific variables --- */
for (pp = preserve; *pp; pp++) {
q = e->val + 5;
for (p = strtok(p, ":"); p; p = strtok(0, ":")) {
- if (p[0] == '.')
+ if (p[0] != '/')
continue;
while (*p)
*q++ = *p++;
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 */
+ S_ISREG(st.st_mode)) /* Check it's a file */
break;
}
} else {
if (setuid(rq.to) == -1)
die("couldn't set uid: %s", strerror(errno));
+ fflush(0);
execve(rq.cmd, todo, env);
die("couldn't exec `%s': %s", rq.cmd, strerror(errno));
return (127);