diff options
| author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-09-14 17:03:18 +0000 |
|---|---|---|
| committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-09-14 17:03:18 +0000 |
| commit | 50776c99c95cbab8d018d025ed8558b9a3bfb1d4 (patch) | |
| tree | 405572e1feb682ca498c5556173f168f58817242 | |
| parent | 866893937a18228b1913f63178bb0c819198adac (diff) | |
| download | busybox-w32-50776c99c95cbab8d018d025ed8558b9a3bfb1d4.tar.gz busybox-w32-50776c99c95cbab8d018d025ed8558b9a3bfb1d4.tar.bz2 busybox-w32-50776c99c95cbab8d018d025ed8558b9a3bfb1d4.zip | |
login: eliminate forward decls and #ifdefs
git-svn-id: svn://busybox.net/trunk/busybox@16123 69ca8d6d-28ef-0310-b511-8ec308f3f277
| -rw-r--r-- | loginutils/login.c | 357 |
1 files changed, 166 insertions, 191 deletions
diff --git a/loginutils/login.c b/loginutils/login.c index 2c23a8d50..78a2ba117 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
| @@ -15,13 +15,6 @@ | |||
| 15 | #include <errno.h> | 15 | #include <errno.h> |
| 16 | #endif | 16 | #endif |
| 17 | 17 | ||
| 18 | /* import from utmp.c | ||
| 19 | * XXX: FIXME: provide empty bodies if ENABLE_FEATURE_UTMP == 0 | ||
| 20 | */ | ||
| 21 | static struct utmp utent; | ||
| 22 | static void read_or_build_utent(int); | ||
| 23 | static void write_utent(const char *); | ||
| 24 | |||
| 25 | enum { | 18 | enum { |
| 26 | TIMEOUT = 60, | 19 | TIMEOUT = 60, |
| 27 | EMPTY_USERNAME_COUNT = 10, | 20 | EMPTY_USERNAME_COUNT = 10, |
| @@ -29,16 +22,176 @@ enum { | |||
| 29 | TTYNAME_SIZE = 32, | 22 | TTYNAME_SIZE = 32, |
| 30 | }; | 23 | }; |
| 31 | 24 | ||
| 32 | static void die_if_nologin_and_non_root(int amroot); | 25 | static char full_tty[TTYNAME_SIZE]; |
| 26 | static char* short_tty = full_tty; | ||
| 27 | |||
| 28 | #if ENABLE_FEATURE_UTMP | ||
| 29 | /* vv Taken from tinylogin utmp.c vv */ | ||
| 30 | /* | ||
| 31 | * read_or_build_utent - see if utmp file is correct for this process | ||
| 32 | * | ||
| 33 | * System V is very picky about the contents of the utmp file | ||
| 34 | * and requires that a slot for the current process exist. | ||
| 35 | * The utmp file is scanned for an entry with the same process | ||
| 36 | * ID. If no entry exists the process exits with a message. | ||
| 37 | * | ||
| 38 | * The "picky" flag is for network and other logins that may | ||
| 39 | * use special flags. It allows the pid checks to be overridden. | ||
| 40 | * This means that getty should never invoke login with any | ||
| 41 | * command line flags. | ||
| 42 | */ | ||
| 43 | static struct utmp utent; | ||
| 44 | static void read_or_build_utent(int picky) | ||
| 45 | { | ||
| 46 | struct utmp *ut; | ||
| 47 | pid_t pid = getpid(); | ||
| 48 | |||
| 49 | setutent(); | ||
| 50 | |||
| 51 | /* First, try to find a valid utmp entry for this process. */ | ||
| 52 | while ((ut = getutent())) | ||
| 53 | if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] && | ||
| 54 | (ut->ut_type == LOGIN_PROCESS || ut->ut_type == USER_PROCESS)) | ||
| 55 | break; | ||
| 56 | |||
| 57 | /* If there is one, just use it, otherwise create a new one. */ | ||
| 58 | if (ut) { | ||
| 59 | utent = *ut; | ||
| 60 | } else { | ||
| 61 | if (picky) | ||
| 62 | bb_error_msg_and_die("no utmp entry found"); | ||
| 63 | |||
| 64 | memset(&utent, 0, sizeof(utent)); | ||
| 65 | utent.ut_type = LOGIN_PROCESS; | ||
| 66 | utent.ut_pid = pid; | ||
| 67 | strncpy(utent.ut_line, short_tty, sizeof(utent.ut_line)); | ||
| 68 | /* This one is only 4 chars wide. Try to fit something | ||
| 69 | * remotely meaningful by skipping "tty"... */ | ||
| 70 | strncpy(utent.ut_id, short_tty + 3, sizeof(utent.ut_id)); | ||
| 71 | strncpy(utent.ut_user, "LOGIN", sizeof(utent.ut_user)); | ||
| 72 | utent.ut_time = time(NULL); | ||
| 73 | } | ||
| 74 | if (!picky) /* root login */ | ||
| 75 | memset(utent.ut_host, 0, sizeof(utent.ut_host)); | ||
| 76 | } | ||
| 77 | |||
| 78 | /* | ||
| 79 | * write_utent - put a USER_PROCESS entry in the utmp file | ||
| 80 | * | ||
| 81 | * write_utent changes the type of the current utmp entry to | ||
| 82 | * USER_PROCESS. the wtmp file will be updated as well. | ||
| 83 | */ | ||
| 84 | static void write_utent(const char *username) | ||
| 85 | { | ||
| 86 | utent.ut_type = USER_PROCESS; | ||
| 87 | strncpy(utent.ut_user, username, sizeof(utent.ut_user)); | ||
| 88 | utent.ut_time = time(NULL); | ||
| 89 | /* other fields already filled in by read_or_build_utent above */ | ||
| 90 | setutent(); | ||
| 91 | pututline(&utent); | ||
| 92 | endutent(); | ||
| 93 | #if ENABLE_FEATURE_WTMP | ||
| 94 | if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) { | ||
| 95 | close(creat(bb_path_wtmp_file, 0664)); | ||
| 96 | } | ||
| 97 | updwtmp(bb_path_wtmp_file, &utent); | ||
| 98 | #endif | ||
| 99 | } | ||
| 100 | #else /* !CONFIG_FEATURE_UTMP */ | ||
| 101 | static inline void read_or_build_utent(int) {} | ||
| 102 | static inline void write_utent(const char *) {} | ||
| 103 | #endif /* !CONFIG_FEATURE_UTMP */ | ||
| 104 | |||
| 105 | static void die_if_nologin_and_non_root(int amroot) | ||
| 106 | { | ||
| 107 | FILE *fp; | ||
| 108 | int c; | ||
| 109 | |||
| 110 | if (access(bb_path_nologin_file, F_OK)) | ||
| 111 | return; | ||
| 112 | |||
| 113 | fp = fopen(bb_path_nologin_file, "r"); | ||
| 114 | if (fp) { | ||
| 115 | while ((c = getc(fp)) != EOF) | ||
| 116 | putchar((c=='\n') ? '\r' : c); | ||
| 117 | fflush(stdout); | ||
| 118 | fclose(fp); | ||
| 119 | } else | ||
| 120 | puts("\r\nSystem closed for routine maintenance\r"); | ||
| 121 | if (!amroot) | ||
| 122 | exit(1); | ||
| 123 | puts("\r\n[Disconnect bypassed -- root login allowed.]\r"); | ||
| 124 | } | ||
| 33 | 125 | ||
| 34 | #if ENABLE_FEATURE_SECURETTY | 126 | #if ENABLE_FEATURE_SECURETTY |
| 35 | static int check_securetty(void); | 127 | static int check_securetty(void) |
| 128 | { | ||
| 129 | FILE *fp; | ||
| 130 | int i; | ||
| 131 | char buf[BUFSIZ]; | ||
| 132 | |||
| 133 | fp = fopen(bb_path_securetty_file, "r"); | ||
| 134 | if (!fp) { | ||
| 135 | /* A missing securetty file is not an error. */ | ||
| 136 | return 1; | ||
| 137 | } | ||
| 138 | while (fgets(buf, sizeof(buf)-1, fp)) { | ||
| 139 | for(i = strlen(buf)-1; i>=0; --i) { | ||
| 140 | if (!isspace(buf[i])) | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | buf[++i] = '\0'; | ||
| 144 | if ((buf[0]=='\0') || (buf[0]=='#')) | ||
| 145 | continue; | ||
| 146 | if (strcmp(buf, short_tty) == 0) { | ||
| 147 | fclose(fp); | ||
| 148 | return 1; | ||
| 149 | } | ||
| 150 | } | ||
| 151 | fclose(fp); | ||
| 152 | return 0; | ||
| 153 | } | ||
| 36 | #else | 154 | #else |
| 37 | static inline int check_securetty(void) { return 1; } | 155 | static inline int check_securetty(void) { return 1; } |
| 38 | #endif | 156 | #endif |
| 39 | 157 | ||
| 40 | static void get_username_or_die(char *buf, int size_buf); | 158 | static void get_username_or_die(char *buf, int size_buf) |
| 41 | static void motd(void); | 159 | { |
| 160 | int c, cntdown; | ||
| 161 | cntdown = EMPTY_USERNAME_COUNT; | ||
| 162 | prompt: | ||
| 163 | /* skip whitespace */ | ||
| 164 | print_login_prompt(); | ||
| 165 | do { | ||
| 166 | c = getchar(); | ||
| 167 | if (c == EOF) exit(1); | ||
| 168 | if (c == '\n') { | ||
| 169 | if (!--cntdown) exit(1); | ||
| 170 | goto prompt; | ||
| 171 | } | ||
| 172 | } while (isspace(c)); | ||
| 173 | |||
| 174 | *buf++ = c; | ||
| 175 | if (!fgets(buf, size_buf-2, stdin)) | ||
| 176 | exit(1); | ||
| 177 | if (!strchr(buf, '\n')) | ||
| 178 | exit(1); | ||
| 179 | while (isgraph(*buf)) buf++; | ||
| 180 | *buf = '\0'; | ||
| 181 | } | ||
| 182 | |||
| 183 | static void motd(void) | ||
| 184 | { | ||
| 185 | FILE *fp; | ||
| 186 | int c; | ||
| 187 | |||
| 188 | fp = fopen(bb_path_motd_file, "r"); | ||
| 189 | if (fp) { | ||
| 190 | while ((c = getc(fp)) != EOF) | ||
| 191 | putchar(c); | ||
| 192 | fclose(fp); | ||
| 193 | } | ||
| 194 | } | ||
| 42 | 195 | ||
| 43 | static void nonblock(int fd) | 196 | static void nonblock(int fd) |
| 44 | { | 197 | { |
| @@ -56,11 +209,6 @@ static void alarm_handler(int sig ATTRIBUTE_UNUSED) | |||
| 56 | exit(EXIT_SUCCESS); | 209 | exit(EXIT_SUCCESS); |
| 57 | } | 210 | } |
| 58 | 211 | ||
| 59 | |||
| 60 | static char full_tty[TTYNAME_SIZE]; | ||
| 61 | static char* short_tty = full_tty; | ||
| 62 | |||
| 63 | |||
| 64 | int login_main(int argc, char **argv) | 212 | int login_main(int argc, char **argv) |
| 65 | { | 213 | { |
| 66 | char fromhost[512]; | 214 | char fromhost[512]; |
| @@ -122,11 +270,7 @@ int login_main(int argc, char **argv) | |||
| 122 | short_tty = full_tty + 5; | 270 | short_tty = full_tty + 5; |
| 123 | } | 271 | } |
| 124 | 272 | ||
| 125 | if (ENABLE_FEATURE_UTMP) { | 273 | read_or_build_utent(!amroot); |
| 126 | read_or_build_utent(!amroot); | ||
| 127 | if (amroot) | ||
| 128 | memset(utent.ut_host, 0, sizeof(utent.ut_host)); | ||
| 129 | } | ||
| 130 | 274 | ||
| 131 | if (opt_host) { | 275 | if (opt_host) { |
| 132 | if (ENABLE_FEATURE_UTMP) | 276 | if (ENABLE_FEATURE_UTMP) |
| @@ -183,8 +327,7 @@ auth_failed: | |||
| 183 | alarm(0); | 327 | alarm(0); |
| 184 | die_if_nologin_and_non_root(pw->pw_uid == 0); | 328 | die_if_nologin_and_non_root(pw->pw_uid == 0); |
| 185 | 329 | ||
| 186 | if (ENABLE_FEATURE_UTMP) | 330 | write_utent(username); |
| 187 | write_utent(username); | ||
| 188 | 331 | ||
| 189 | #ifdef CONFIG_SELINUX | 332 | #ifdef CONFIG_SELINUX |
| 190 | if (is_selinux_enabled()) { | 333 | if (is_selinux_enabled()) { |
| @@ -255,171 +398,3 @@ auth_failed: | |||
| 255 | 398 | ||
| 256 | return EXIT_FAILURE; | 399 | return EXIT_FAILURE; |
| 257 | } | 400 | } |
| 258 | |||
| 259 | |||
| 260 | static void get_username_or_die(char *buf, int size_buf) | ||
| 261 | { | ||
| 262 | int c, cntdown; | ||
| 263 | cntdown = EMPTY_USERNAME_COUNT; | ||
| 264 | prompt: | ||
| 265 | /* skip whitespace */ | ||
| 266 | print_login_prompt(); | ||
| 267 | do { | ||
| 268 | c = getchar(); | ||
| 269 | if (c == EOF) exit(1); | ||
| 270 | if (c == '\n') { | ||
| 271 | if (!--cntdown) exit(1); | ||
| 272 | goto prompt; | ||
| 273 | } | ||
| 274 | } while (isspace(c)); | ||
| 275 | |||
| 276 | *buf++ = c; | ||
| 277 | if (!fgets(buf, size_buf-2, stdin)) | ||
| 278 | exit(1); | ||
| 279 | if (!strchr(buf, '\n')) | ||
| 280 | exit(1); | ||
| 281 | while (isgraph(*buf)) buf++; | ||
| 282 | *buf = '\0'; | ||
| 283 | } | ||
| 284 | |||
| 285 | |||
| 286 | static void die_if_nologin_and_non_root(int amroot) | ||
| 287 | { | ||
| 288 | FILE *fp; | ||
| 289 | int c; | ||
| 290 | |||
| 291 | if (access(bb_path_nologin_file, F_OK)) | ||
| 292 | return; | ||
| 293 | |||
| 294 | fp = fopen(bb_path_nologin_file, "r"); | ||
| 295 | if (fp) { | ||
| 296 | while ((c = getc(fp)) != EOF) | ||
| 297 | putchar((c=='\n') ? '\r' : c); | ||
| 298 | fflush(stdout); | ||
| 299 | fclose(fp); | ||
| 300 | } else | ||
| 301 | puts("\r\nSystem closed for routine maintenance\r"); | ||
| 302 | if (!amroot) | ||
| 303 | exit(1); | ||
| 304 | puts("\r\n[Disconnect bypassed -- root login allowed.]\r"); | ||
| 305 | } | ||
| 306 | |||
| 307 | #if ENABLE_FEATURE_SECURETTY | ||
| 308 | |||
| 309 | static int check_securetty(void) | ||
| 310 | { | ||
| 311 | FILE *fp; | ||
| 312 | int i; | ||
| 313 | char buf[BUFSIZ]; | ||
| 314 | |||
| 315 | fp = fopen(bb_path_securetty_file, "r"); | ||
| 316 | if (!fp) { | ||
| 317 | /* A missing securetty file is not an error. */ | ||
| 318 | return 1; | ||
| 319 | } | ||
| 320 | while (fgets(buf, sizeof(buf)-1, fp)) { | ||
| 321 | for(i = strlen(buf)-1; i>=0; --i) { | ||
| 322 | if (!isspace(buf[i])) | ||
| 323 | break; | ||
| 324 | } | ||
| 325 | buf[++i] = '\0'; | ||
| 326 | if ((buf[0]=='\0') || (buf[0]=='#')) | ||
| 327 | continue; | ||
| 328 | if (strcmp(buf, short_tty) == 0) { | ||
| 329 | fclose(fp); | ||
| 330 | return 1; | ||
| 331 | } | ||
| 332 | } | ||
| 333 | fclose(fp); | ||
| 334 | return 0; | ||
| 335 | } | ||
| 336 | |||
| 337 | #endif | ||
| 338 | |||
| 339 | static void motd(void) | ||
| 340 | { | ||
| 341 | FILE *fp; | ||
| 342 | int c; | ||
| 343 | |||
| 344 | fp = fopen(bb_path_motd_file, "r"); | ||
| 345 | if (fp) { | ||
| 346 | while ((c = getc(fp)) != EOF) | ||
| 347 | putchar(c); | ||
| 348 | fclose(fp); | ||
| 349 | } | ||
| 350 | } | ||
| 351 | |||
| 352 | |||
| 353 | #if ENABLE_FEATURE_UTMP | ||
| 354 | /* vv Taken from tinylogin utmp.c vv */ | ||
| 355 | |||
| 356 | /* | ||
| 357 | * read_or_build_utent - see if utmp file is correct for this process | ||
| 358 | * | ||
| 359 | * System V is very picky about the contents of the utmp file | ||
| 360 | * and requires that a slot for the current process exist. | ||
| 361 | * The utmp file is scanned for an entry with the same process | ||
| 362 | * ID. If no entry exists the process exits with a message. | ||
| 363 | * | ||
| 364 | * The "picky" flag is for network and other logins that may | ||
| 365 | * use special flags. It allows the pid checks to be overridden. | ||
| 366 | * This means that getty should never invoke login with any | ||
| 367 | * command line flags. | ||
| 368 | */ | ||
| 369 | |||
| 370 | static void read_or_build_utent(int picky) | ||
| 371 | { | ||
| 372 | struct utmp *ut; | ||
| 373 | pid_t pid = getpid(); | ||
| 374 | |||
| 375 | setutent(); | ||
| 376 | |||
| 377 | /* First, try to find a valid utmp entry for this process. */ | ||
| 378 | while ((ut = getutent())) | ||
| 379 | if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] && | ||
| 380 | (ut->ut_type == LOGIN_PROCESS || ut->ut_type == USER_PROCESS)) | ||
| 381 | break; | ||
| 382 | |||
| 383 | /* If there is one, just use it, otherwise create a new one. */ | ||
| 384 | if (ut) { | ||
| 385 | utent = *ut; | ||
| 386 | } else { | ||
| 387 | if (picky) | ||
| 388 | bb_error_msg_and_die("no utmp entry found"); | ||
| 389 | |||
| 390 | memset(&utent, 0, sizeof(utent)); | ||
| 391 | utent.ut_type = LOGIN_PROCESS; | ||
| 392 | utent.ut_pid = pid; | ||
| 393 | strncpy(utent.ut_line, short_tty, sizeof(utent.ut_line)); | ||
| 394 | /* This one is only 4 chars wide. Try to fit something | ||
| 395 | * remotely meaningful by skipping "tty"... */ | ||
| 396 | strncpy(utent.ut_id, short_tty + 3, sizeof(utent.ut_id)); | ||
| 397 | strncpy(utent.ut_user, "LOGIN", sizeof(utent.ut_user)); | ||
| 398 | utent.ut_time = time(NULL); | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 402 | /* | ||
| 403 | * write_utent - put a USER_PROCESS entry in the utmp file | ||
| 404 | * | ||
| 405 | * write_utent changes the type of the current utmp entry to | ||
| 406 | * USER_PROCESS. the wtmp file will be updated as well. | ||
| 407 | */ | ||
| 408 | |||
| 409 | static void write_utent(const char *username) | ||
| 410 | { | ||
| 411 | utent.ut_type = USER_PROCESS; | ||
| 412 | strncpy(utent.ut_user, username, sizeof(utent.ut_user)); | ||
| 413 | utent.ut_time = time(NULL); | ||
| 414 | /* other fields already filled in by read_or_build_utent above */ | ||
| 415 | setutent(); | ||
| 416 | pututline(&utent); | ||
| 417 | endutent(); | ||
| 418 | #if ENABLE_FEATURE_WTMP | ||
| 419 | if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) { | ||
| 420 | close(creat(bb_path_wtmp_file, 0664)); | ||
| 421 | } | ||
| 422 | updwtmp(bb_path_wtmp_file, &utent); | ||
| 423 | #endif | ||
| 424 | } | ||
| 425 | #endif /* CONFIG_FEATURE_UTMP */ | ||
