aboutsummaryrefslogtreecommitdiff
path: root/loginutils/su.c
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-08-29 07:38:56 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-08-29 07:38:56 +0000
commita6b7bdcf8caaf1fd36f522a795f1c4c5ff3c64ce (patch)
tree1fc6d3abf73bcb92368aa71585eeb6c5c447190c /loginutils/su.c
parentdc72f3ace2575f6ee2c0ee8662aa0373265d4883 (diff)
downloadbusybox-w32-a6b7bdcf8caaf1fd36f522a795f1c4c5ff3c64ce.tar.gz
busybox-w32-a6b7bdcf8caaf1fd36f522a795f1c4c5ff3c64ce.tar.bz2
busybox-w32-a6b7bdcf8caaf1fd36f522a795f1c4c5ff3c64ce.zip
Vodz, last patch 105
Busybox "mount" applet unsupport "user" option and result: must have _BB_SUID_NEVER applet option (my bug). Last patch have reducing 216 bytes for "su" applet also.
Diffstat (limited to 'loginutils/su.c')
-rw-r--r--loginutils/su.c140
1 files changed, 66 insertions, 74 deletions
diff --git a/loginutils/su.c b/loginutils/su.c
index 85f5cbe7b..04c213e4e 100644
--- a/loginutils/su.c
+++ b/loginutils/su.c
@@ -29,77 +29,57 @@
29 29
30 30
31#if defined( SYSLOG_SUCCESS ) || defined( SYSLOG_FAILURE ) 31#if defined( SYSLOG_SUCCESS ) || defined( SYSLOG_FAILURE )
32/* Log the fact that someone has run su to the user given by PW; 32/* Log the fact that someone has run su */
33 if SUCCESSFUL is nonzero, they gave the correct password, etc. */
34 33
35static void log_su ( const struct passwd *pw, int successful ) 34# if defined( SYSLOG_SUCCESS ) && defined( SYSLOG_FAILURE )
35static void log_su (const char *successful, const char *old_user, const char *tty)
36{ 36{
37 const char *old_user, *tty; 37 syslog ( LOG_NOTICE, "%s%s on %s", successful, old_user, tty);
38
39#if !defined( SYSLOG_SUCESS )
40 if ( successful )
41 return;
42#endif
43#if !defined( SYSLOG_FAILURE )
44 if ( !successful )
45 return;
46#endif
47
48 if ( pw-> pw_uid ) // not to root -> ignored
49 return;
50
51 /* The utmp entry (via getlogin) is probably the best way to identify
52 the user, especially if someone su's from a su-shell. */
53 old_user = getlogin ( );
54 if ( !old_user ) {
55 /* getlogin can fail -- usually due to lack of utmp entry. Resort to getpwuid. */
56 struct passwd *pwd = getpwuid ( getuid ( ));
57 old_user = ( pwd ? pwd-> pw_name : "" );
58 }
59
60 tty = ttyname ( 2 );
61
62 openlog ( "su", 0, LOG_AUTH );
63 syslog ( LOG_NOTICE, "%s%s on %s", successful ? "" : "FAILED SU ", old_user, tty ? tty : "none" );
64} 38}
39# define log_su_successful(cu, u, tty) if(!cu) log_su("", u, tty)
40# define log_su_failure(cu, u, tty) if(!cu) log_su("FAILED SU ", u, tty)
41# else
42 /* partial logging */
43# if !defined( SYSLOG_SUCESS )
44# define log_su_successful(cu, u, tty)
45# define log_su_failure(cu, u, t) if(!cu) \
46 syslog(LOG_NOTICE, "FAILED SU %s on %s", u, t)
47# else
48# define log_su_successful(cu, u, t) if(!cu) \
49 syslog(LOG_NOTICE, "%s on %s", u, t)
50# define log_su_failure(cu, u, tty)
51# endif
52# endif
53#else
54 /* logging not used */
55# define log_su_successful(cu, u, tty)
56# define log_su_failure(cu, u, tty)
65#endif 57#endif
66 58
67 59
68
69int su_main ( int argc, char **argv ) 60int su_main ( int argc, char **argv )
70{ 61{
71 int flag; 62 unsigned long flags;
72 int opt_preserve = 0; 63 int opt_preserve;
73 int opt_loginshell = 0; 64 int opt_loginshell;
74 char *opt_shell = 0; 65 char *opt_shell = 0;
75 char *opt_command = 0; 66 char *opt_command = 0;
76 char *opt_username = DEFAULT_USER; 67 char *opt_username = DEFAULT_USER;
77 char **opt_args = 0; 68 char **opt_args = 0;
78 struct passwd *pw, pw_copy; 69 struct passwd *pw;
79 70 uid_t cur_uid = getuid();
80 71
81 while (( flag = getopt ( argc, argv, "c:lmps:" )) != -1 ) { 72#if defined( SYSLOG_SUCCESS ) || defined( SYSLOG_FAILURE )
82 switch ( flag ) { 73 const char *tty;
83 case 'c': 74 const char *old_user;
84 opt_command = optarg; 75#endif
85 break;
86 case 'm':
87 case 'p':
88 opt_preserve = 1;
89 break;
90 case 's':
91 opt_shell = optarg;
92 break;
93 case 'l':
94 opt_loginshell = 1;
95 break;
96 default:
97 bb_show_usage( );
98 break;
99 }
100 }
101 76
102 if (( optind < argc ) && ( argv [optind][0] == '-' ) && ( argv [optind][1] == 0 )) { 77 flags = bb_getopt_ulflags(argc, argv, "mplc:s:",
78 &opt_command, &opt_shell);
79 opt_preserve = flags & 3;
80 opt_loginshell = (flags & 4 ? 1 : 0);
81
82 if (optind < argc && argv[optind][0] == '-' && argv[optind][1] == 0) {
103 opt_loginshell = 1; 83 opt_loginshell = 1;
104 ++optind; 84 ++optind;
105 } 85 }
@@ -111,6 +91,24 @@ int su_main ( int argc, char **argv )
111 if ( optind < argc ) 91 if ( optind < argc )
112 opt_args = argv + optind; 92 opt_args = argv + optind;
113 93
94#if defined( SYSLOG_SUCCESS ) || defined( SYSLOG_FAILURE )
95#ifdef CONFIG_FEATURE_U_W_TMP
96 /* The utmp entry (via getlogin) is probably the best way to identify
97 the user, especially if someone su's from a su-shell. */
98 old_user = getlogin ( );
99 if ( !old_user )
100#endif
101 {
102 /* getlogin can fail -- usually due to lack of utmp entry. Resort to getpwuid. */
103 pw = getpwuid ( cur_uid );
104 old_user = ( pw ? pw->pw_name : "" );
105 }
106 tty = ttyname ( 2 );
107 if(!tty)
108 tty = "none";
109
110 openlog ( bb_applet_name, 0, LOG_AUTH );
111#endif
114 112
115 pw = getpwnam ( opt_username ); 113 pw = getpwnam ( opt_username );
116 if ( !pw ) 114 if ( !pw )
@@ -122,27 +120,21 @@ int su_main ( int argc, char **argv )
122 if ( !pw-> pw_shell || !pw->pw_shell [0] ) 120 if ( !pw-> pw_shell || !pw->pw_shell [0] )
123 pw-> pw_shell = (char *) DEFAULT_SHELL; 121 pw-> pw_shell = (char *) DEFAULT_SHELL;
124 122
125 /* Make a copy of the password information and point pw at the local 123 if ((( cur_uid == 0 ) || correct_password ( pw ))) {
126 copy instead. Otherwise, some systems (e.g. Linux) would clobber 124 log_su_successful(pw->pw_uid, old_user, tty );
127 the static data through the getlogin call from log_su. */ 125 } else {
128 pw_copy = *pw; 126 log_su_failure (pw->pw_uid, old_user, tty );
129 pw = &pw_copy;
130 pw-> pw_name = bb_xstrdup ( pw-> pw_name );
131 pw-> pw_dir = bb_xstrdup ( pw-> pw_dir );
132 pw-> pw_shell = bb_xstrdup ( pw-> pw_shell );
133
134 if (( getuid ( ) == 0 ) || correct_password ( pw ))
135 log_su ( pw, 1 );
136 else {
137 log_su ( pw, 0 );
138 bb_error_msg_and_die ( "incorrect password" ); 127 bb_error_msg_and_die ( "incorrect password" );
139 } 128 }
140 129
130#if defined( SYSLOG_SUCCESS ) || defined( SYSLOG_FAILURE )
131 closelog();
132#endif
133
141 if ( !opt_shell && opt_preserve ) 134 if ( !opt_shell && opt_preserve )
142 opt_shell = getenv ( "SHELL" ); 135 opt_shell = getenv ( "SHELL" );
143 136
144 if ( opt_shell && getuid ( ) && restricted_shell ( pw-> pw_shell )) 137 if ( opt_shell && cur_uid && restricted_shell ( pw-> pw_shell )) {
145 {
146 /* The user being su'd to has a nonstandard shell, and so is 138 /* The user being su'd to has a nonstandard shell, and so is
147 probably a uucp account or has restricted access. Don't 139 probably a uucp account or has restricted access. Don't
148 compromise the account by allowing access with a standard 140 compromise the account by allowing access with a standard
@@ -152,7 +144,7 @@ int su_main ( int argc, char **argv )
152 } 144 }
153 145
154 if ( !opt_shell ) 146 if ( !opt_shell )
155 opt_shell = bb_xstrdup ( pw-> pw_shell ); 147 opt_shell = pw->pw_shell;
156 148
157 change_identity ( pw ); 149 change_identity ( pw );
158 setup_environment ( opt_shell, opt_loginshell, !opt_preserve, pw ); 150 setup_environment ( opt_shell, opt_loginshell, !opt_preserve, pw );