/* * get_current_utmp - return the most probable utmp entry for the current * session * * The utmp file is scanned for an entry with the same process ID. * The line enterred by the *getty / telnetd, etc. should also match * the current terminal. * * When an entry is returned by get_current_utmp, and if the utmp * structure has a ut_id field, this field should be used to update * the entry information. * * Return NULL if no entries exist in utmp for the current process. */ /*@null@*/ /*@only@*/struct utmp *get_current_utmp (void) { struct utmp *ut; struct utmp *ret = NULL; setutent (); /* First, try to find a valid utmp entry for this process. */ while ((ut = getutent ()) != NULL) { if ( (ut->ut_pid == getpid ()) #ifdef HAVE_STRUCT_UTMP_UT_ID && ('\0' != ut->ut_id[0]) #endif #ifdef HAVE_STRUCT_UTMP_UT_TYPE && ( (LOGIN_PROCESS == ut->ut_type) || (USER_PROCESS == ut->ut_type)) #endif /* A process may have failed to close an entry * Check if this entry refers to the current tty */ && is_my_tty (ut->ut_line)) { break; } } if (NULL != ut) { ret = (struct utmp *) xmalloc (sizeof (*ret)); memcpy (ret, ut, sizeof (*ret)); } endutent (); return ret; }
extern int login_main(int argc, char **argv) { char tty[BUFSIZ]; char full_tty[200]; char fromhost[512]; char username[USERNAME_SIZE]; const char *tmp; int amroot; int flag; int failed; int count=0; struct passwd *pw, pw_copy; #ifdef CONFIG_WHEEL_GROUP struct group *grp; #endif int opt_preserve = 0; int opt_fflag = 0; char *opt_host = 0; int alarmstarted = 0; #ifdef CONFIG_SELINUX int flask_enabled = is_flask_enabled(); security_id_t sid = 0, old_tty_sid, new_tty_sid; #endif username[0]=0; amroot = ( getuid ( ) == 0 ); signal ( SIGALRM, alarm_handler ); alarm ( TIMEOUT ); alarmstarted = 1; while (( flag = getopt(argc, argv, "f:h:p")) != EOF ) { switch ( flag ) { case 'p': opt_preserve = 1; break; case 'f': /* * username must be a separate token * (-f root, *NOT* -froot). --marekm */ if ( optarg != argv[optind-1] ) bb_show_usage( ); if ( !amroot ) /* Auth bypass only if real UID is zero */ bb_error_msg_and_die ( "-f permission denied" ); safe_strncpy(username, optarg, USERNAME_SIZE); opt_fflag = 1; break; case 'h': opt_host = optarg; break; default: bb_show_usage( ); } } if (optind < argc) // user from command line (getty) safe_strncpy(username, argv[optind], USERNAME_SIZE); if ( !isatty ( 0 ) || !isatty ( 1 ) || !isatty ( 2 )) return EXIT_FAILURE; /* Must be a terminal */ #ifdef CONFIG_FEATURE_U_W_TMP checkutmp ( !amroot ); #endif tmp = ttyname ( 0 ); if ( tmp && ( strncmp ( tmp, "/dev/", 5 ) == 0 )) safe_strncpy ( tty, tmp + 5, sizeof( tty )); else if ( tmp && *tmp == '/' ) safe_strncpy ( tty, tmp, sizeof( tty )); else safe_strncpy ( tty, "UNKNOWN", sizeof( tty )); #ifdef CONFIG_FEATURE_U_W_TMP if ( amroot ) memset ( utent.ut_host, 0, sizeof utent.ut_host ); #endif if ( opt_host ) { #ifdef CONFIG_FEATURE_U_W_TMP safe_strncpy ( utent.ut_host, opt_host, sizeof( utent. ut_host )); #endif snprintf ( fromhost, sizeof( fromhost ) - 1, " on `%.100s' from `%.200s'", tty, opt_host ); } else snprintf ( fromhost, sizeof( fromhost ) - 1, " on `%.100s'", tty ); setpgrp(); openlog ( "login", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH ); while ( 1 ) { failed = 0; if ( !username[0] ) if(!login_prompt ( username )) return EXIT_FAILURE; if ( !alarmstarted && ( TIMEOUT > 0 )) { alarm ( TIMEOUT ); alarmstarted = 1; } if (!( pw = getpwnam ( username ))) { pw_copy.pw_name = "UNKNOWN"; pw_copy.pw_passwd = "!"; opt_fflag = 0; failed = 1; } else pw_copy = *pw; pw = &pw_copy; if (( pw-> pw_passwd [0] == '!' ) || ( pw-> pw_passwd[0] == '*' )) failed = 1; if ( opt_fflag ) { opt_fflag = 0; goto auth_ok; } if (!failed && ( pw-> pw_uid == 0 ) && ( !check_tty ( tty ))) failed = 1; /* Don't check the password if password entry is empty (!) */ if ( !pw-> pw_passwd[0] ) goto auth_ok; /* authorization takes place here */ if ( correct_password ( pw )) goto auth_ok; failed = 1; auth_ok: if ( !failed) break; { // delay next try time_t start, now; time ( &start ); now = start; while ( difftime ( now, start ) < FAIL_DELAY) { sleep ( FAIL_DELAY ); time ( &now ); } } puts("Login incorrect"); username[0] = 0; if ( ++count == 3 ) { syslog ( LOG_WARNING, "invalid password for `%s'%s\n", pw->pw_name, fromhost); return EXIT_FAILURE; } } alarm ( 0 ); if ( check_nologin ( pw-> pw_uid == 0 )) return EXIT_FAILURE; #ifdef CONFIG_FEATURE_U_W_TMP setutmp ( username, tty ); #endif #ifdef CONFIG_SELINUX if (flask_enabled) { struct stat st; if (get_default_sid(username, 0, &sid)) { fprintf(stderr, "Unable to get SID for %s\n", username); exit(1); } if (stat_secure(tty, &st, &old_tty_sid)) { fprintf(stderr, "stat_secure(%.100s) failed: %.100s\n", tty, strerror(errno)); return EXIT_FAILURE; } if (security_change_sid (sid, old_tty_sid, SECCLASS_CHR_FILE, &new_tty_sid) != 0) { fprintf(stderr, "security_change_sid(%.100s) failed: %.100s\n", tty, strerror(errno)); return EXIT_FAILURE; } if(chsid(tty, new_tty_sid) != 0) { fprintf(stderr, "chsid(%.100s, %d) failed: %.100s\n", tty, new_tty_sid, strerror(errno)); return EXIT_FAILURE; } } else sid = 0; #endif if ( *tty != '/' ) snprintf ( full_tty, sizeof( full_tty ) - 1, "/dev/%s", tty); else safe_strncpy ( full_tty, tty, sizeof( full_tty ) - 1 ); if ( !is_my_tty ( full_tty )) syslog ( LOG_ERR, "unable to determine TTY name, got %s\n", full_tty ); /* Try these, but don't complain if they fail * (for example when the root fs is read only) */ chown ( full_tty, pw-> pw_uid, pw-> pw_gid ); chmod ( full_tty, 0600 ); change_identity ( pw ); tmp = pw-> pw_shell; if(!tmp || !*tmp) tmp = DEFAULT_SHELL; setup_environment ( tmp, 1, !opt_preserve, pw ); motd ( ); signal ( SIGALRM, SIG_DFL ); /* default alarm signal */ if ( pw-> pw_uid == 0 ) syslog ( LOG_INFO, "root login %s\n", fromhost ); run_shell ( tmp, 1, 0, 0 #ifdef CONFIG_SELINUX , sid #endif ); /* exec the shell finally. */ return EXIT_FAILURE; }
static int modeset_new(Modeset **out) { _cleanup_(modeset_freep) Modeset *m = NULL; int r; assert(out); m = new0(Modeset, 1); if (!m) return log_oom(); r = sd_pid_get_session(getpid(), &m->session); if (r < 0) return log_error_errno(r, "Cannot retrieve logind session: %m"); r = sd_session_get_seat(m->session, &m->seat); if (r < 0) return log_error_errno(r, "Cannot retrieve seat of logind session: %m"); m->my_tty = is_my_tty(m->session); m->managed = m->my_tty && geteuid() > 0; m->r = rand() % 0xff; m->g = rand() % 0xff; m->b = rand() % 0xff; m->r_up = m->g_up = m->b_up = true; r = sd_event_default(&m->event); if (r < 0) return r; r = sd_bus_open_system(&m->bus); if (r < 0) return r; r = sd_bus_attach_event(m->bus, m->event, SD_EVENT_PRIORITY_NORMAL); if (r < 0) return r; r = sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1); if (r < 0) return r; r = sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL); if (r < 0) return r; r = sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL); if (r < 0) return r; r = sd_event_add_exit(m->event, &m->exit_src, modeset_exit_fn, m); if (r < 0) return r; /* schedule before sd-bus close */ r = sd_event_source_set_priority(m->exit_src, -10); if (r < 0) return r; r = sysview_context_new(&m->sysview, SYSVIEW_CONTEXT_SCAN_LOGIND | SYSVIEW_CONTEXT_SCAN_DRM, m->event, m->bus, NULL); if (r < 0) return r; r = grdev_context_new(&m->grdev, m->event, m->bus); if (r < 0) return r; *out = m; m = NULL; return 0; }