Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/loginutils/login.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 137  static void die_if_nologin(void) Line 137  static void die_if_nologin(void)
137   puts("\r\nSystem closed for routine maintenance\r");   puts("\r\nSystem closed for routine maintenance\r");
138    
139   fclose(fp);   fclose(fp);
140   fflush(NULL);   fflush_all();
141   /* Users say that they do need this prior to exit: */   /* Users say that they do need this prior to exit: */
142   tcdrain(STDOUT_FILENO);   tcdrain(STDOUT_FILENO);
143   exit(EXIT_FAILURE);   exit(EXIT_FAILURE);
# Line 165  static int check_securetty(void) Line 165  static int check_securetty(void)
165  static ALWAYS_INLINE int check_securetty(void) { return 1; }  static ALWAYS_INLINE int check_securetty(void) { return 1; }
166  #endif  #endif
167    
168    #if ENABLE_SELINUX
169    static void initselinux(char *username, char *full_tty,
170     security_context_t *user_sid)
171    {
172     security_context_t old_tty_sid, new_tty_sid;
173    
174     if (!is_selinux_enabled())
175     return;
176    
177     if (get_default_context(username, NULL, user_sid)) {
178     bb_error_msg_and_die("can't get SID for %s", username);
179     }
180     if (getfilecon(full_tty, &old_tty_sid) < 0) {
181     bb_perror_msg_and_die("getfilecon(%s) failed", full_tty);
182     }
183     if (security_compute_relabel(*user_sid, old_tty_sid,
184     SECCLASS_CHR_FILE, &new_tty_sid) != 0) {
185     bb_perror_msg_and_die("security_change_sid(%s) failed", full_tty);
186     }
187     if (setfilecon(full_tty, new_tty_sid) != 0) {
188     bb_perror_msg_and_die("chsid(%s, %s) failed", full_tty, new_tty_sid);
189     }
190    }
191    #endif
192    
193    #if ENABLE_LOGIN_SCRIPTS
194    static void run_login_script(struct passwd *pw, char *full_tty)
195    {
196     char *t_argv[2];
197    
198     t_argv[0] = getenv("LOGIN_PRE_SUID_SCRIPT");
199     if (t_argv[0]) {
200     t_argv[1] = NULL;
201     xsetenv("LOGIN_TTY", full_tty);
202     xsetenv("LOGIN_USER", pw->pw_name);
203     xsetenv("LOGIN_UID", utoa(pw->pw_uid));
204     xsetenv("LOGIN_GID", utoa(pw->pw_gid));
205     xsetenv("LOGIN_SHELL", pw->pw_shell);
206     spawn_and_wait(t_argv); /* NOMMU-friendly */
207     unsetenv("LOGIN_TTY");
208     unsetenv("LOGIN_USER");
209     unsetenv("LOGIN_UID");
210     unsetenv("LOGIN_GID");
211     unsetenv("LOGIN_SHELL");
212     }
213    }
214    #else
215    void run_login_script(struct passwd *pw, char *full_tty);
216    #endif
217    
218  static void get_username_or_die(char *buf, int size_buf)  static void get_username_or_die(char *buf, int size_buf)
219  {  {
220   int c, cntdown;   int c, cntdown;
# Line 175  static void get_username_or_die(char *bu Line 225  static void get_username_or_die(char *bu
225   /* skip whitespace */   /* skip whitespace */
226   do {   do {
227   c = getchar();   c = getchar();
228   if (c == EOF) exit(EXIT_FAILURE);   if (c == EOF)
229     exit(EXIT_FAILURE);
230   if (c == '\n') {   if (c == '\n') {
231   if (!--cntdown) exit(EXIT_FAILURE);   if (!--cntdown)
232     exit(EXIT_FAILURE);
233   goto prompt;   goto prompt;
234   }   }
235   } while (isspace(c));   } while (isspace(c)); /* maybe isblank? */
236    
237   *buf++ = c;   *buf++ = c;
238   if (!fgets(buf, size_buf-2, stdin))   if (!fgets(buf, size_buf-2, stdin))
239   exit(EXIT_FAILURE);   exit(EXIT_FAILURE);
240   if (!strchr(buf, '\n'))   if (!strchr(buf, '\n'))
241   exit(EXIT_FAILURE);   exit(EXIT_FAILURE);
242   while (isgraph(*buf)) buf++;   while ((unsigned char)*buf > ' ')
243     buf++;
244   *buf = '\0';   *buf = '\0';
245  }  }
246    
# Line 197  static void motd(void) Line 250  static void motd(void)
250    
251   fd = open(bb_path_motd_file, O_RDONLY);   fd = open(bb_path_motd_file, O_RDONLY);
252   if (fd >= 0) {   if (fd >= 0) {
253   fflush(stdout);   fflush_all();
254   bb_copyfd_eof(fd, STDOUT_FILENO);   bb_copyfd_eof(fd, STDOUT_FILENO);
255   close(fd);   close(fd);
256   }   }
# Line 210  static void alarm_handler(int sig UNUSED Line 263  static void alarm_handler(int sig UNUSED
263   * We don't want to block here */   * We don't want to block here */
264   ndelay_on(1);   ndelay_on(1);
265   printf("\r\nLogin timed out after %d seconds\r\n", TIMEOUT);   printf("\r\nLogin timed out after %d seconds\r\n", TIMEOUT);
266   fflush(stdout);   fflush_all();
267   /* unix API is brain damaged regarding O_NONBLOCK,   /* unix API is brain damaged regarding O_NONBLOCK,
268   * we should undo it, or else we can affect other processes */   * we should undo it, or else we can affect other processes */
269   ndelay_off(1);   ndelay_off(1);
# Line 234  int login_main(int argc UNUSED_PARAM, ch Line 287  int login_main(int argc UNUSED_PARAM, ch
287   struct passwd *pw;   struct passwd *pw;
288   char *opt_host = opt_host; /* for compiler */   char *opt_host = opt_host; /* for compiler */
289   char *opt_user = opt_user; /* for compiler */   char *opt_user = opt_user; /* for compiler */
290   char full_tty[TTYNAME_SIZE];   char *full_tty;
291   USE_SELINUX(security_context_t user_sid = NULL;)   IF_SELINUX(security_context_t user_sid = NULL;)
292   USE_FEATURE_UTMP(struct utmp utent;)   IF_FEATURE_UTMP(struct utmp utent;)
293  #if ENABLE_PAM  #if ENABLE_PAM
294   int pamret;   int pamret;
295   pam_handle_t *pamh;   pam_handle_t *pamh;
# Line 246  int login_main(int argc UNUSED_PARAM, ch Line 299  int login_main(int argc UNUSED_PARAM, ch
299   char pwdbuf[256];   char pwdbuf[256];
300  #endif  #endif
301    
  short_tty = full_tty;  
302   username[0] = '\0';   username[0] = '\0';
303   signal(SIGALRM, alarm_handler);   signal(SIGALRM, alarm_handler);
304   alarm(TIMEOUT);   alarm(TIMEOUT);
# Line 272  int login_main(int argc UNUSED_PARAM, ch Line 324  int login_main(int argc UNUSED_PARAM, ch
324   safe_strncpy(username, argv[0], sizeof(username));   safe_strncpy(username, argv[0], sizeof(username));
325    
326   /* Let's find out and memorize our tty */   /* Let's find out and memorize our tty */
327   if (!isatty(0) || !isatty(1) || !isatty(2))   if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO))
328   return EXIT_FAILURE; /* Must be a terminal */   return EXIT_FAILURE; /* Must be a terminal */
329   safe_strncpy(full_tty, "UNKNOWN", sizeof(full_tty));   full_tty = xmalloc_ttyname(STDIN_FILENO);
330   tmp = ttyname(0);   if (!full_tty)
331   if (tmp) {   full_tty = xstrdup("UNKNOWN");
332   safe_strncpy(full_tty, tmp, sizeof(full_tty));   short_tty = full_tty;
333   if (strncmp(full_tty, "/dev/", 5) == 0)   if (strncmp(full_tty, "/dev/", 5) == 0)
334   short_tty = full_tty + 5;   short_tty += 5;
  }  
335    
336   read_or_build_utent(&utent, run_by_root);   read_or_build_utent(&utent, run_by_root);
337    
338   if (opt & LOGIN_OPT_h) {   if (opt & LOGIN_OPT_h) {
339   USE_FEATURE_UTMP(   IF_FEATURE_UTMP(safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));)
  safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));  
  )  
340   fromhost = xasprintf(" on '%s' from '%s'", short_tty, opt_host);   fromhost = xasprintf(" on '%s' from '%s'", short_tty, opt_host);
341   } else   } else {
342   fromhost = xasprintf(" on '%s'", short_tty);   fromhost = xasprintf(" on '%s'", short_tty);
343     }
344    
345   /* Was breaking "login <username>" from shell command line: */   /* Was breaking "login <username>" from shell command line: */
346   /*bb_setpgrp();*/   /*bb_setpgrp();*/
347    
348   openlog(applet_name, LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);   openlog(applet_name, LOG_PID | LOG_CONS, LOG_AUTH);
349    
350   while (1) {   while (1) {
351   /* flush away any type-ahead (as getty does) */   /* flush away any type-ahead (as getty does) */
# Line 362  int login_main(int argc UNUSED_PARAM, ch Line 412  int login_main(int argc UNUSED_PARAM, ch
412   break; /* success, continue login process */   break; /* success, continue login process */
413    
414   pam_auth_failed:   pam_auth_failed:
415   bb_error_msg("pam_%s call failed: %s (%d)", failed_msg,   /* syslog, because we don't want potential attacker
416     * to know _why_ login failed */
417     syslog(LOG_WARNING, "pam_%s call failed: %s (%d)", failed_msg,
418   pam_strerror(pamh, pamret), pamret);   pam_strerror(pamh, pamret), pamret);
419   safe_strncpy(username, "UNKNOWN", sizeof(username));   safe_strncpy(username, "UNKNOWN", sizeof(username));
420  #else /* not PAM */  #else /* not PAM */
# Line 410  int login_main(int argc UNUSED_PARAM, ch Line 462  int login_main(int argc UNUSED_PARAM, ch
462    
463   write_utent(&utent, username);   write_utent(&utent, username);
464    
465  #if ENABLE_SELINUX   IF_SELINUX(initselinux(username, full_tty, &user_sid));
  if (is_selinux_enabled()) {  
  security_context_t old_tty_sid, new_tty_sid;  
466    
  if (get_default_context(username, NULL, &user_sid)) {  
  bb_error_msg_and_die("cannot get SID for %s",  
  username);  
  }  
  if (getfilecon(full_tty, &old_tty_sid) < 0) {  
  bb_perror_msg_and_die("getfilecon(%s) failed",  
  full_tty);  
  }  
  if (security_compute_relabel(user_sid, old_tty_sid,  
  SECCLASS_CHR_FILE, &new_tty_sid) != 0) {  
  bb_perror_msg_and_die("security_change_sid(%s) failed",  
  full_tty);  
  }  
  if (setfilecon(full_tty, new_tty_sid) != 0) {  
  bb_perror_msg_and_die("chsid(%s, %s) failed",  
  full_tty, new_tty_sid);  
  }  
  }  
 #endif  
467   /* Try these, but don't complain if they fail.   /* Try these, but don't complain if they fail.
468   * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */   * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */
469   fchown(0, pw->pw_uid, pw->pw_gid);   fchown(0, pw->pw_uid, pw->pw_gid);
470   fchmod(0, 0600);   fchmod(0, 0600);
471    
472   /* We trust environment only if we run by root */   /* We trust environment only if we run by root */
473   if (ENABLE_LOGIN_SCRIPTS && run_by_root) {   if (ENABLE_LOGIN_SCRIPTS && run_by_root)
474   char *t_argv[2];   run_login_script(pw, full_tty);
   
  t_argv[0] = getenv("LOGIN_PRE_SUID_SCRIPT");  
  if (t_argv[0]) {  
  t_argv[1] = NULL;  
  xsetenv("LOGIN_TTY", full_tty);  
  xsetenv("LOGIN_USER", pw->pw_name);  
  xsetenv("LOGIN_UID", utoa(pw->pw_uid));  
  xsetenv("LOGIN_GID", utoa(pw->pw_gid));  
  xsetenv("LOGIN_SHELL", pw->pw_shell);  
  spawn_and_wait(t_argv); /* NOMMU-friendly */  
  unsetenv("LOGIN_TTY"  );  
  unsetenv("LOGIN_USER" );  
  unsetenv("LOGIN_UID"  );  
  unsetenv("LOGIN_GID"  );  
  unsetenv("LOGIN_SHELL");  
  }  
  }  
475    
476   change_identity(pw);   change_identity(pw);
477   tmp = pw->pw_shell;   tmp = pw->pw_shell;
# Line 470  int login_main(int argc UNUSED_PARAM, ch Line 484  int login_main(int argc UNUSED_PARAM, ch
484    
485   if (pw->pw_uid == 0)   if (pw->pw_uid == 0)
486   syslog(LOG_INFO, "root login%s", fromhost);   syslog(LOG_INFO, "root login%s", fromhost);
487  #if ENABLE_SELINUX  
488   /* well, a simple setexeccon() here would do the job as well,   /* well, a simple setexeccon() here would do the job as well,
489   * but let's play the game for now */   * but let's play the game for now */
490   set_current_security_context(user_sid);   IF_SELINUX(set_current_security_context(user_sid);)
 #endif  
491    
492   // util-linux login also does:   // util-linux login also does:
493   // /* start new session */   // /* start new session */

Legend:
Removed from v.983  
changed lines
  Added in v.984