diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-09-17 14:45:09 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-09-17 14:45:09 +0000 |
commit | 66fabdb6313caae9ad30cb66a3820402c3f90d97 (patch) | |
tree | 793cc1a11116caf897b1d58f0765193da61798d8 | |
parent | 4d0f54af9485103deff702347e118dd11e1a373c (diff) | |
download | busybox-w32-66fabdb6313caae9ad30cb66a3820402c3f90d97.tar.gz busybox-w32-66fabdb6313caae9ad30cb66a3820402c3f90d97.tar.bz2 busybox-w32-66fabdb6313caae9ad30cb66a3820402c3f90d97.zip |
login: apply fixes + getopt_ulflag'ification by Bernhard
-rw-r--r-- | loginutils/login.c | 73 |
1 files changed, 29 insertions, 44 deletions
diff --git a/loginutils/login.c b/loginutils/login.c index 78a2ba117..0157bace8 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -40,7 +40,9 @@ static char* short_tty = full_tty; | |||
40 | * This means that getty should never invoke login with any | 40 | * This means that getty should never invoke login with any |
41 | * command line flags. | 41 | * command line flags. |
42 | */ | 42 | */ |
43 | |||
43 | static struct utmp utent; | 44 | static struct utmp utent; |
45 | |||
44 | static void read_or_build_utent(int picky) | 46 | static void read_or_build_utent(int picky) |
45 | { | 47 | { |
46 | struct utmp *ut; | 48 | struct utmp *ut; |
@@ -97,10 +99,10 @@ static void write_utent(const char *username) | |||
97 | updwtmp(bb_path_wtmp_file, &utent); | 99 | updwtmp(bb_path_wtmp_file, &utent); |
98 | #endif | 100 | #endif |
99 | } | 101 | } |
100 | #else /* !CONFIG_FEATURE_UTMP */ | 102 | #else /* !ENABLE_FEATURE_UTMP */ |
101 | static inline void read_or_build_utent(int) {} | 103 | static inline void read_or_build_utent(int ATTRIBUTE_UNUSED picky) {} |
102 | static inline void write_utent(const char *) {} | 104 | static inline void write_utent(const char ATTRIBUTE_UNUSED *username) {} |
103 | #endif /* !CONFIG_FEATURE_UTMP */ | 105 | #endif /* !ENABLE_FEATURE_UTMP */ |
104 | 106 | ||
105 | static void die_if_nologin_and_non_root(int amroot) | 107 | static void die_if_nologin_and_non_root(int amroot) |
106 | { | 108 | { |
@@ -211,53 +213,35 @@ static void alarm_handler(int sig ATTRIBUTE_UNUSED) | |||
211 | 213 | ||
212 | int login_main(int argc, char **argv) | 214 | int login_main(int argc, char **argv) |
213 | { | 215 | { |
216 | enum { | ||
217 | LOGIN_OPT_f = (1<<0), | ||
218 | LOGIN_OPT_h = (1<<1), | ||
219 | LOGIN_OPT_p = (1<<2), | ||
220 | }; | ||
214 | char fromhost[512]; | 221 | char fromhost[512]; |
215 | char username[USERNAME_SIZE]; | 222 | char username[USERNAME_SIZE]; |
216 | const char *tmp; | 223 | const char *tmp; |
217 | int amroot; | 224 | int amroot; |
218 | int flag; | 225 | unsigned long opt; |
219 | int count = 0; | 226 | int count = 0; |
220 | struct passwd *pw; | 227 | struct passwd *pw; |
221 | int opt_preserve = 0; | 228 | char *opt_host = NULL; |
222 | int opt_fflag = 0; | 229 | char *opt_user = NULL; |
223 | char *opt_host = 0; | 230 | USE_SELINUX(security_context_t user_sid = NULL;) |
224 | #ifdef CONFIG_SELINUX | ||
225 | security_context_t user_sid = NULL; | ||
226 | #endif | ||
227 | 231 | ||
228 | username[0] = '\0'; | 232 | username[0] = '\0'; |
229 | amroot = (getuid() == 0); | 233 | amroot = (getuid() == 0); |
230 | signal(SIGALRM, alarm_handler); | 234 | signal(SIGALRM, alarm_handler); |
231 | alarm(TIMEOUT); | 235 | alarm(TIMEOUT); |
232 | 236 | ||
233 | while ((flag = getopt(argc, argv, "f:h:p")) != EOF) { | 237 | opt = bb_getopt_ulflags(argc, argv, "f:h:p", &opt_user, &opt_host); |
234 | switch (flag) { | 238 | |
235 | case 'p': | 239 | if (opt & LOGIN_OPT_f) { |
236 | opt_preserve = 1; | 240 | if (!amroot) |
237 | break; | 241 | bb_error_msg_and_die("-f is for root only"); |
238 | case 'f': | 242 | safe_strncpy(username, opt_user, strlen(opt_user)); |
239 | /* | ||
240 | * username must be a separate token | ||
241 | * (-f root, *NOT* -froot). --marekm | ||
242 | */ | ||
243 | if (optarg != argv[optind-1]) | ||
244 | bb_show_usage(); | ||
245 | |||
246 | if (!amroot) /* Auth bypass only if real UID is zero */ | ||
247 | bb_error_msg_and_die("-f is for root only"); | ||
248 | |||
249 | safe_strncpy(username, optarg, sizeof(username)); | ||
250 | opt_fflag = 1; | ||
251 | break; | ||
252 | case 'h': | ||
253 | opt_host = optarg; | ||
254 | break; | ||
255 | default: | ||
256 | bb_show_usage(); | ||
257 | } | ||
258 | } | 243 | } |
259 | if (optind < argc) /* user from command line (getty) */ | 244 | username[USERNAME_SIZE] = 0; |
260 | safe_strncpy(username, argv[optind], sizeof(username)); | ||
261 | 245 | ||
262 | /* Let's find out and memorize our tty */ | 246 | /* Let's find out and memorize our tty */ |
263 | if (!isatty(0) || !isatty(1) || !isatty(2)) | 247 | if (!isatty(0) || !isatty(1) || !isatty(2)) |
@@ -273,8 +257,9 @@ int login_main(int argc, char **argv) | |||
273 | read_or_build_utent(!amroot); | 257 | read_or_build_utent(!amroot); |
274 | 258 | ||
275 | if (opt_host) { | 259 | if (opt_host) { |
276 | if (ENABLE_FEATURE_UTMP) | 260 | USE_FEATURE_UTMP( |
277 | safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host)); | 261 | safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host)); |
262 | ) | ||
278 | snprintf(fromhost, sizeof(fromhost)-1, " on `%.100s' from " | 263 | snprintf(fromhost, sizeof(fromhost)-1, " on `%.100s' from " |
279 | "`%.200s'", short_tty, opt_host); | 264 | "`%.200s'", short_tty, opt_host); |
280 | } | 265 | } |
@@ -298,7 +283,7 @@ int login_main(int argc, char **argv) | |||
298 | if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') | 283 | if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') |
299 | goto auth_failed; | 284 | goto auth_failed; |
300 | 285 | ||
301 | if (opt_fflag) | 286 | if (opt & LOGIN_OPT_f) |
302 | break; /* -f USER: success without asking passwd */ | 287 | break; /* -f USER: success without asking passwd */ |
303 | 288 | ||
304 | if (pw->pw_uid == 0 && !check_securetty()) | 289 | if (pw->pw_uid == 0 && !check_securetty()) |
@@ -306,14 +291,14 @@ int login_main(int argc, char **argv) | |||
306 | 291 | ||
307 | /* Don't check the password if password entry is empty (!) */ | 292 | /* Don't check the password if password entry is empty (!) */ |
308 | if (!pw->pw_passwd[0]) | 293 | if (!pw->pw_passwd[0]) |
309 | break; | 294 | break; |
310 | 295 | ||
311 | /* authorization takes place here */ | 296 | /* authorization takes place here */ |
312 | if (correct_password(pw)) | 297 | if (correct_password(pw)) |
313 | break; | 298 | break; |
314 | 299 | ||
315 | auth_failed: | 300 | auth_failed: |
316 | opt_fflag = 0; | 301 | opt &= ~LOGIN_OPT_f; |
317 | bb_do_delay(FAIL_DELAY); | 302 | bb_do_delay(FAIL_DELAY); |
318 | puts("Login incorrect"); | 303 | puts("Login incorrect"); |
319 | if (++count == 3) { | 304 | if (++count == 3) { |
@@ -382,7 +367,7 @@ auth_failed: | |||
382 | tmp = pw->pw_shell; | 367 | tmp = pw->pw_shell; |
383 | if (!tmp || !*tmp) | 368 | if (!tmp || !*tmp) |
384 | tmp = DEFAULT_SHELL; | 369 | tmp = DEFAULT_SHELL; |
385 | setup_environment(tmp, 1, !opt_preserve, pw); | 370 | setup_environment(tmp, 1, !(opt & LOGIN_OPT_p), pw); |
386 | 371 | ||
387 | motd(); | 372 | motd(); |
388 | signal(SIGALRM, SIG_DFL); /* default alarm signal */ | 373 | signal(SIGALRM, SIG_DFL); /* default alarm signal */ |