Patch from Tito to make syslog configurable and remove #ifdefs. Further

cleanups by me.
This commit is contained in:
Rob Landley 2006-07-10 03:05:46 +00:00
parent cba1b96735
commit 3bfcf3cccc
2 changed files with 51 additions and 112 deletions

View File

@ -142,6 +142,13 @@ config CONFIG_SU
Note that Busybox binary must be setuid root for this applet to Note that Busybox binary must be setuid root for this applet to
work properly. work properly.
config CONFIG_SU_SYSLOG
bool "Support for syslog in su"
default y
depends on CONFIG_SU
help
Enables support for syslog in su.
config CONFIG_SULOGIN config CONFIG_SULOGIN
bool "sulogin" bool "sulogin"
default n default n

View File

@ -1,65 +1,15 @@
/* vi: set sw=4 ts=4: */ /* vi: set sw=4 ts=4: */
/* /*
Licensed under the GPL v2, see the file LICENSE in this tarball. * Mini su implementation for busybox
*/ *
* Licensed under the GPL v2, see the file LICENSE in this tarball.
#include <fcntl.h> */
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <termios.h>
#include <unistd.h>
#include <utmp.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#include <time.h>
#include "busybox.h" #include "busybox.h"
#include <signal.h>
/* The shell to run if none is given in the user's passwd entry. */ #include <syslog.h>
#ifndef DEFAULT_SHELL #include <sys/resource.h>
#define DEFAULT_SHELL "/bin/sh" #include <time.h>
#endif
/* Default user. */
#define DEFAULT_USER "root"
/* #define SYSLOG_SUCCESS */
#define SYSLOG_FAILURE
#if defined( SYSLOG_SUCCESS ) || defined( SYSLOG_FAILURE )
/* Log the fact that someone has run su */
# if defined( SYSLOG_SUCCESS ) && defined( SYSLOG_FAILURE )
static void log_su (const char *successful, const char *old_user,
const char *tty)
{
syslog ( LOG_NOTICE, "%s%s on %s", successful, old_user, tty);
}
# define log_su_successful(cu, u, tty) if(!cu) log_su("", u, tty)
# define log_su_failure(cu, u, tty) if(!cu) log_su("FAILED SU ", u, tty)
# else
/* partial logging */
# if !defined( SYSLOG_SUCESS )
# define log_su_successful(cu, u, tty)
# define log_su_failure(cu, u, t) if(!cu) \
syslog(LOG_NOTICE, "FAILED SU %s on %s", u, t)
# else
# define log_su_successful(cu, u, t) if(!cu) \
syslog(LOG_NOTICE, "%s on %s", u, t)
# define log_su_failure(cu, u, tty)
# endif
# endif
#else
/* logging not used */
# define log_su_successful(cu, u, tty)
# define log_su_failure(cu, u, tty)
#endif
int su_main ( int argc, char **argv ) int su_main ( int argc, char **argv )
@ -67,20 +17,15 @@ int su_main ( int argc, char **argv )
unsigned long flags; unsigned long flags;
char *opt_shell = 0; char *opt_shell = 0;
char *opt_command = 0; char *opt_command = 0;
char *opt_username = DEFAULT_USER; char *opt_username = "root";
char **opt_args = 0; char **opt_args = 0;
struct passwd *pw; struct passwd *pw;
uid_t cur_uid = getuid(); uid_t cur_uid = getuid();
#if defined( SYSLOG_SUCCESS ) || defined( SYSLOG_FAILURE )
const char *tty; const char *tty;
const char *old_user; char *old_user;
#endif
flags = bb_getopt_ulflags(argc, argv, "mplc:s:", flags = bb_getopt_ulflags(argc, argv, "mplc:s:", &opt_command, &opt_shell);
&opt_command, &opt_shell); #define SU_OPT_mp (3)
#define SU_OPT_m (3)
#define SU_OPT_p (3)
#define SU_OPT_l (4) #define SU_OPT_l (4)
if (optind < argc && argv[optind][0] == '-' && argv[optind][1] == 0) { if (optind < argc && argv[optind][0] == '-' && argv[optind][1] == 0) {
@ -89,73 +34,60 @@ int su_main ( int argc, char **argv )
} }
/* get user if specified */ /* get user if specified */
if ( optind < argc ) if (optind < argc) opt_username = argv [optind++];
opt_username = argv [optind++];
if ( optind < argc ) if (optind < argc) opt_args = argv + optind;
opt_args = argv + optind;
#if defined( SYSLOG_SUCCESS ) || defined( SYSLOG_FAILURE ) if (ENABLE_SU_SYSLOG) {
#ifdef CONFIG_FEATURE_UTMP /* The utmp entry (via getlogin) is probably the best way to identify
/* The utmp entry (via getlogin) is probably the best way to identify the user, especially if someone su's from a su-shell.
the user, especially if someone su's from a su-shell. */ But getlogin can fail -- usually due to lack of utmp entry.
old_user = getlogin ( ); in this case resort to getpwuid. */
if ( !old_user ) old_user = bb_xstrdup(USE_FEATURE_UTMP(getlogin() ? : ) (pw = getpwuid(cur_uid)) ? pw->pw_name : "");
#endif tty = ttyname(2) ? : "none";
{ openlog(bb_applet_name, 0, LOG_AUTH);
/* getlogin can fail -- usually due to lack of utmp entry.
Resort to getpwuid. */
pw = getpwuid ( cur_uid );
old_user = ( pw ? pw->pw_name : "" );
} }
tty = ttyname ( 2 );
if(!tty)
tty = "none";
openlog ( bb_applet_name, 0, LOG_AUTH ); pw = getpwnam(opt_username);
#endif if (!pw) bb_error_msg_and_die("Unknown id: %s", opt_username);
pw = getpwnam ( opt_username );
if ( !pw )
bb_error_msg_and_die ( "user %s does not exist", opt_username );
/* Make sure pw->pw_shell is non-NULL. It may be NULL when NEW_USER /* Make sure pw->pw_shell is non-NULL. It may be NULL when NEW_USER
is a username that is retrieved via NIS (YP), but that doesn't have is a username that is retrieved via NIS (YP), but that doesn't have
a default shell listed. */ a default shell listed. */
if ( !pw->pw_shell || !pw->pw_shell [0] ) if (!pw->pw_shell || !pw->pw_shell[0]) pw->pw_shell = (char *)DEFAULT_SHELL;
pw->pw_shell = (char *) DEFAULT_SHELL;
if ((( cur_uid == 0 ) || correct_password ( pw ))) { if ((cur_uid == 0) || correct_password(pw)) {
log_su_successful(pw->pw_uid, old_user, tty ); if (ENABLE_SU_SYSLOG)
syslog(LOG_NOTICE, "+ %s %s:%s", tty, old_user, opt_username);
} else { } else {
log_su_failure (pw->pw_uid, old_user, tty ); if (ENABLE_SU_SYSLOG)
bb_error_msg_and_die ( "incorrect password" ); syslog(LOG_NOTICE, "- %s %s:%s", tty, old_user, opt_username);
bb_error_msg_and_die("incorrect password");
} }
#if defined( SYSLOG_SUCCESS ) || defined( SYSLOG_FAILURE ) if (ENABLE_FEATURE_CLEAN_UP && ENABLE_SU_SYSLOG) {
closelog(); closelog();
#endif free(old_user);
}
if ( !opt_shell && (flags & SU_OPT_p)) if (!opt_shell && (flags & SU_OPT_mp)) opt_shell = getenv("SHELL");
opt_shell = getenv ( "SHELL" );
if ( opt_shell && cur_uid && restricted_shell ( pw->pw_shell )) { if (opt_shell && cur_uid && restricted_shell(pw->pw_shell)) {
/* The user being su'd to has a nonstandard shell, and so is /* The user being su'd to has a nonstandard shell, and so is
probably a uucp account or has restricted access. Don't probably a uucp account or has restricted access. Don't
compromise the account by allowing access with a standard compromise the account by allowing access with a standard
shell. */ shell. */
fputs ( "using restricted shell\n", stderr ); bb_error_msg("using restricted shell");
opt_shell = 0; opt_shell = 0;
} }
if ( !opt_shell ) if (!opt_shell) opt_shell = pw->pw_shell;
opt_shell = pw->pw_shell;
change_identity ( pw ); change_identity(pw);
setup_environment(opt_shell, flags & SU_OPT_l, !(flags & SU_OPT_p), pw); setup_environment(opt_shell, flags & SU_OPT_l, !(flags & SU_OPT_mp), pw);
#if ENABLE_SELINUX USE_SELINUX(set_current_security_context(NULL);)
set_current_security_context(NULL);
#endif /* Returns only on error */
run_shell(opt_shell, flags & SU_OPT_l, opt_command, (const char**)opt_args); run_shell(opt_shell, flags & SU_OPT_l, opt_command, (const char**)opt_args);
return EXIT_FAILURE; return EXIT_FAILURE;