Exemplo n.º 1
0
static void
CheckUtmp( void )
{
	static time_t modtim;
	time_t nck;
	time_t ends;
	struct utmps *utp, **utpp;
	struct stat st;
#ifdef BSD_UTMP
	int fd;
	struct utmp ut[1];
#else
	STRUCTUTMP *ut;
#endif

	if (!utmpList)
		return;
	if (stat( UTMP_FILE, &st )) {
		LogError( UTMP_FILE " not found - cannot use console mode\n" );
		bombUtmp();
		return;
	}
	if (modtim != st.st_mtime) {
		Debug( "rescanning " UTMP_FILE "\n" );
		for (utp = utmpList; utp; utp = utp->next)
			utp->state = UtDead;
#ifdef BSD_UTMP
		if ((fd = open( UTMP_FILE, O_RDONLY )) < 0) {
			LogError( "Cannot open " UTMP_FILE " - cannot use console mode\n" );
			bombUtmp();
			return;
		}
		while (Reader( fd, ut, sizeof(ut[0]) ) == sizeof(ut[0]))
#else
		SETUTENT();
		while ((ut = GETUTENT()))
#endif
		{
			for (utp = utmpList; utp; utp = utp->next) {
#ifdef HAVE_VTS
				char **line;
				for (line = consoleTTYs; *line; line++)
					if (!strncmp( *line, ut->ut_line, sizeof(ut->ut_line) ))
						goto hitlin;
				continue;
			  hitlin:
#else
				if (strncmp( utp->d->console, ut->ut_line, sizeof(ut->ut_line) ))
					continue;
#endif
#ifdef BSD_UTMP
				if (!*ut->ut_user) {
#else
				if (ut->ut_type != USER_PROCESS) {
#endif
#ifdef HAVE_VTS
					if (utp->state == UtActive)
						break;
#endif
					utp->state = UtWait;
				} else {
					utp->hadSess = 1;
					utp->state = UtActive;
				}
				if (utp->time < ut->ut_time) /* theoretically superfluous */
					utp->time = ut->ut_time;
				break;
			}
		}
#ifdef BSD_UTMP
		close( fd );
#else
		ENDUTENT();
#endif
		modtim = st.st_mtime;
	}
	for (utpp = &utmpList; (utp = *utpp); ) {
		if (utp->state != UtActive) {
			if (utp->state == UtDead) /* shouldn't happen ... */
				utp->time = 0;
			ends = utp->time + (utp->hadSess ? TIME_RELOG : TIME_LOG);
			if (ends <= now) {
#ifdef HAVE_VTS
				ForEachDisplay( WakeDisplay );
				Debug( "console login timed out\n" );
#else
				utp->d->status = notRunning;
				Debug( "console login for %s at %s timed out\n",
				       utp->d->name, utp->d->console );
#endif
				*utpp = utp->next;
				free( utp );
				continue;
			} else
				nck = ends;
		} else
			nck = TIME_RELOG + now;
		if (nck < utmpTimeout)
			utmpTimeout = nck;
		utpp = &(*utpp)->next;
	}
}

static void
#ifdef HAVE_VTS
SwitchToTty( void )
#else
SwitchToTty( struct display *d )
#endif
{
	struct utmps *utp;
#ifdef HAVE_VTS
	int vt;
#endif

	if (!(utp = Malloc( sizeof(*utp) ))) {
#ifdef HAVE_VTS
		ForEachDisplay( WakeDisplay );
#else
		d->status = notRunning;
#endif
		return;
	}
#ifndef HAVE_VTS
	d->status = textMode;
	utp->d = d;
#endif
	utp->time = now;
	utp->hadSess = 0;
	utp->next = utmpList;
	utmpList = utp;
	CheckUtmp();

#ifdef HAVE_VTS
	if ((vt = TTYtoVT( *consoleTTYs )))
		activateVT( vt );
#endif

	/* XXX output something useful here */
}

#ifdef HAVE_VTS
static void
StopToTTY( struct display *d )
{
	if ((d->displayType & d_location) == dLocal)
		switch (d->status) {
		default:
			rStopDisplay( d, DS_TEXTMODE | 0x100 );
		case reserve:
		case textMode:
			break;
		}
}

static void
CheckTTYMode( void )
{
	struct display *d;

	for (d = displays; d; d = d->next)
		if (d->status == zombie)
			return;

	SwitchToTty();
}

#else

void
SwitchToX( struct display *d )
{
	struct utmps *utp, **utpp;

	for (utpp = &utmpList; (utp = *utpp); utpp = &(*utpp)->next)
		if (utp->d == d) {
			*utpp = utp->next;
			free( utp );
			d->status = notRunning;
			return;
		}
}
#endif

#ifdef XDMCP
static void
StartRemoteLogin( struct display *d )
{
	char **argv;
	int pid;

	Debug( "StartRemoteLogin for %s\n", d->name );
	/* HACK: omitting LoadDisplayResources( d ) here! */
	switch (pid = Fork()) {
	case 0:
		argv = PrepServerArgv( d, d->serverArgsRemote );
		if (!(argv = addStrArr( argv, "-once", 5 )) ||
		    !(argv = addStrArr( argv, "-query", 6 )) ||
		    !(argv = addStrArr( argv, d->remoteHost, -1 )))
			exit( 1 );
		Debug( "exec %\"[s\n", argv );
		(void)execv( argv[0], argv );
		LogError( "X server %\"s cannot be executed\n", argv[0] );
		exit( 1 );
	case -1:
		LogError( "Forking X server for remote login failed: %m" );
		d->status = notRunning;
		return;
	default:
		break;
	}
	Debug( "X server forked, pid %d\n", pid );
	d->serverPid = pid;

	d->status = remoteLogin;
}
Exemplo n.º 2
0
/* Search utmp for the local user */
int
find_user (char *name, char *tty)
{
  UTMP *uptr;
  int status;
  struct stat statb;
  char ftty[sizeof (PATH_DEV) + sizeof (uptr->ut_line)];
  time_t last_time = 0;
  int notty;

  notty = (*tty == '\0');

  status = NOT_HERE;
  strcpy(ftty, PATH_DEV);

  SETUTENT ();

  while ((uptr = GETUTENT ()) != NULL)
    {
#ifdef USER_PROCESS
      if (uptr->ut_type != USER_PROCESS)
	continue;
#endif
      if (!strncmp (uptr->ut_name, name, sizeof(uptr->ut_name)))
	{
	  if (notty)
	    {
	      /* no particular tty was requested */
	      strncpy(ftty + sizeof(PATH_DEV) - 1,
		      uptr->ut_line,
		      sizeof(ftty) - sizeof(PATH_DEV) - 1);
	      ftty[sizeof(ftty) - 1] = 0;

	      if (stat(ftty, &statb) == 0)
		{
		  if (!(statb.st_mode & S_IWGRP))
		    {
		      if (status != SUCCESS)
			status = PERMISSION_DENIED;
		      continue;
		    }
		  if (statb.st_atime > last_time)
		    {
		      last_time = statb.st_atime;
		      strcpy(tty, uptr->ut_line);
		      status = SUCCESS;
		    }
		  continue;
		}
	    }
	  if (!strcmp(uptr->ut_line, tty))
	    {
	      status = SUCCESS;
	      break;
	    }
	}
    }

  ENDUTENT ();
  return status;
}
Exemplo n.º 3
0
static void
checkUtmp(void)
{
    static time_t modtim;
    time_t nck;
    time_t ends;
    struct utmps *utp;
#ifndef HAVE_VTS
    struct utmps **utpp;
#endif
    struct stat st;
#ifdef BSD_UTMP
    int fd;
    struct utmp ut[1];
#else
    STRUCTUTMP *ut;
#endif

    if (!utmpList)
        return;
    if (stat(UTMP_FILE, &st)) {
        logError(UTMP_FILE " not found - cannot use console mode\n");
        wakeDisplays();
        return;
    }
    if (modtim != st.st_mtime) {
        debug("rescanning " UTMP_FILE "\n");
#ifdef HAVE_VTS
        utp = utmpList;
#else
        for (utp = utmpList; utp; utp = utp->next)
#endif
            utp->state = UtDead;
#ifdef BSD_UTMP
        if ((fd = open(UTMP_FILE, O_RDONLY)) < 0) {
            logError("Cannot open " UTMP_FILE " - cannot use console mode\n");
            wakeDisplays();
            return;
        }
        while (reader(fd, ut, sizeof(ut[0])) == sizeof(ut[0]))
#else
        SETUTENT();
        while ((ut = GETUTENT()))
#endif
        {
            /* first, match the tty to a utemps */
#ifdef HAVE_VTS
            char **line;
            for (line = consoleTTYs; *line; line++)
                if (!strncmp(*line, ut->ut_line, sizeof(ut->ut_line)))
#else
            for (utp = utmpList; utp; utp = utp->next)
                if (!strncmp(utp->d->console, ut->ut_line, sizeof(ut->ut_line)))
#endif
                    goto hitlin;
            continue;
          hitlin:
            /* then, update the utemps accordingly */
#ifdef BSD_UTMP
            if (!*ut->ut_user) {
#else
            if (ut->ut_type != USER_PROCESS) {
#endif
#ifdef HAVE_VTS
                /* don't allow "downgrading" the singular utemps */
                if (utp->state == UtActive)
                    continue;
#endif
                utp->state = UtWait;
            } else {
                utp->hadSess = True;
                utp->state = UtActive;
            }
            nck = ut->ut_time - nowWallDelta;
            if (nck > now)
                nck = 0; /* Clock jumped. Time out immediately. */
#ifdef HAVE_VTS
            /* tty with latest activity wins */
            if (utp->time < nck)
#endif
                utp->time = nck;
        }
#ifdef BSD_UTMP
        close(fd);
#else
        ENDUTENT();
#endif
        modtim = st.st_mtime;
    }
#ifdef HAVE_VTS
    utp = utmpList;
#else
    for (utpp = &utmpList; (utp = *utpp);) {
#endif
        if (utp->state != UtActive) {
            if (utp->state == UtDead) /* shouldn't happen ... */
                utp->time = 0;
            ends = utp->time + (utp->hadSess ? TIME_RELOG : TIME_LOG);
            if (ends <= now) {
#ifdef HAVE_VTS
                wakeDisplays();
                debug("console login timed out\n");
                return;
#else
                utp->d->status = notRunning;
                debug("console login for %s at %s timed out\n",
                       utp->d->name, utp->d->console);
                *utpp = utp->next;
                free(utp);
                continue;
#endif
            } else
                nck = ends;
        } else
            nck = TIME_RELOG + now;
        if (nck < utmpTimeout)
            utmpTimeout = nck;
#ifndef HAVE_VTS
        utpp = &(*utpp)->next;
    }
#endif
}

static void
#ifdef HAVE_VTS
switchToTTY(void)
#else
switchToTTY(struct display *d)
#endif
{
    struct utmps *utp;
#ifdef HAVE_VTS
    int vt;
#endif

    if (!(utp = Malloc(sizeof(*utp)))) {
#ifdef HAVE_VTS
        wakeDisplays();
#else
        d->status = notRunning;
#endif
        return;
    }
#ifndef HAVE_VTS
    d->status = textMode;
    utp->d = d;
    utp->next = utmpList;
#endif
    utp->time = now;
    utp->hadSess = False;
    utmpList = utp;
    checkUtmp();

#ifdef HAVE_VTS
    if ((vt = TTYtoVT(*consoleTTYs)))
        activateVT(vt);
#endif
}

#ifdef HAVE_VTS
static void
stopToTTY(struct display *d)
{
    if ((d->displayType & d_location) == dLocal)
        switch (d->status) {
        default:
            rStopDisplay(d, DS_TEXTMODE | DS_SCHEDULE);
        case reserve:
        case textMode:
            break;
        }
}

static void
checkTTYMode(void)
{
    struct display *d;

    for (d = displays; d; d = d->next)
        if (d->status == zombie)
            return;

    switchToTTY();
}

#else

void
switchToX(struct display *d)
{
    struct utmps *utp, **utpp;

    for (utpp = &utmpList; (utp = *utpp); utpp = &(*utpp)->next)
        if (utp->d == d) {
            *utpp = utp->next;
            free(utp);
            d->status = notRunning;
            return;
        }
}
#endif

#ifdef XDMCP
static void
startRemoteLogin(struct display *d)
{
    char **argv;

    debug("startRemoteLogin for %s\n", d->name);
    /* HACK: omitting loadDisplayResources(d) here! */
    switch (Fork(&d->serverPid)) {
    case 0:
        argv = prepareServerArgv(d, d->serverArgsRemote);
        if (!(argv = addStrArr(argv, "-once", 5)) ||
            !(argv = addStrArr(argv, "-query", 6)) ||
            !(argv = addStrArr(argv, d->remoteHost, -1)))
            exit(1);
        debug("exec %\"[s\n", argv);
        (void)execv(argv[0], argv);
        logError("X server %\"s cannot be executed\n", argv[0]);
        exit(1);
    case -1:
        logError("Forking X server for remote login failed: %m");
        d->status = notRunning;
        return;
    default:
        break;
    }
    debug("X server forked, pid %d\n", d->serverPid);

    d->status = remoteLogin;
}
Exemplo n.º 4
0
void ListSessions(int flags, struct display *d, void *ctx, void (*emitXSess)(struct display *, struct display *, void *),
                  void (*emitTTYSess)(STRUCTUTMP *, struct display *, void *))
{
    struct display *di;
#ifdef IP6_MAGIC
    int le, dot;
#endif
#ifdef BSD_UTMP
    int fd;
    struct utmp ut[1];
#else
    STRUCTUTMP *ut;
#endif

    for(di = displays; di; di = di->next)
        if(((flags & lstRemote) || (di->displayType & d_location) == dLocal)
           && (di->status == remoteLogin || ((flags & lstPassive) ? di->status == running : di->userSess >= 0)))
            emitXSess(di, d, ctx);

    if(!(flags & lstTTY))
        return;

#ifdef BSD_UTMP
    if((fd = open(UTMP_FILE, O_RDONLY)) < 0)
        return;
    while(Reader(fd, ut, sizeof(ut[0])) == sizeof(ut[0]))
    {
        if(*ut->ut_user)
        { /* no idea how to list passive TTYs on BSD */
#else
    SETUTENT();
    while((ut = GETUTENT()))
    {
        if(ut->ut_type == USER_PROCESS
#if 0 /* list passive TTYs at all? not too sensible, i think. */
		    || ((flags & lstPassive) && ut->ut_type == LOGIN_PROCESS)
#endif
           )
        {
#endif
            if(*ut->ut_host)
            { /* from remote or x */
                if(!(flags & lstRemote))
                    continue;
            }
            else
            {
                /* hack around broken konsole which does not set ut_host. */
                /* this check is probably linux-specific. */
                /* alternatively we could open the device and try VT_OPENQRY. */
                if(memcmp(ut->ut_line, "tty", 3) || !isdigit(ut->ut_line[3]))
                    continue;
            }
            if(StrNChrCnt(ut->ut_line, sizeof(ut->ut_line), ':'))
                continue; /* x login */
            switch(StrNChrCnt(ut->ut_host, sizeof(ut->ut_host), ':'))
            {
                case 1: /* x terminal */
                    continue;
                default:
#ifdef IP6_MAGIC
                    /* unknown - IPv6 makes things complicated */
                    le = StrNLen(ut->ut_host, sizeof(ut->ut_host));
                    /* cut off screen number */
                    for(dot = le; ut->ut_host[--dot] != ':';)
                        if(ut->ut_host[dot] == '.')
                        {
                            le = dot;
                            break;
                        }
                    for(di = displays; di; di = di->next)
                        if(!memcmp(di->name, ut->ut_host, le) && !di->name[le])
                            goto cont; /* x terminal */
                    break;
                cont:
                    continue;
                case 0: /* no x terminal */
#endif
                    break;
            }
            emitTTYSess(ut, d, ctx);
        }
    }
#ifdef BSD_UTMP
    close(fd);
#else
    ENDUTENT();
#endif
}