diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-08-29 07:38:56 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-08-29 07:38:56 +0000 |
commit | a6b7bdcf8caaf1fd36f522a795f1c4c5ff3c64ce (patch) | |
tree | 1fc6d3abf73bcb92368aa71585eeb6c5c447190c /loginutils/su.c | |
parent | dc72f3ace2575f6ee2c0ee8662aa0373265d4883 (diff) | |
download | busybox-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.c | 140 |
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 | ||
35 | static void log_su ( const struct passwd *pw, int successful ) | 34 | # if defined( SYSLOG_SUCCESS ) && defined( SYSLOG_FAILURE ) |
35 | static 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 | |||
69 | int su_main ( int argc, char **argv ) | 60 | int 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 ); |