Exemple #1
0
static void
whoami(void)
{
	struct utmpx ut, *utx;
	struct passwd *pwd;
	const char *name, *tty;

	if ((tty = ttyname(STDIN_FILENO)) == NULL)
		tty = "tty??";
	else if (strncmp(tty, _PATH_DEV, sizeof _PATH_DEV - 1) == 0)
		tty += sizeof _PATH_DEV - 1;
	strlcpy(ut.ut_line, tty, sizeof ut.ut_line);

	/* Search utmp for our tty, dump first matching record. */
	if ((utx = getutxline(&ut)) != NULL && utx->ut_type == USER_PROCESS) {
		row(utx);
		return;
	}

	/* Not found; fill the utmp structure with the information we have. */
	memset(&ut, 0, sizeof(ut));
	if ((pwd = getpwuid(getuid())) != NULL)
		name = pwd->pw_name;
	else
		name = "?";
	strlcpy(ut.ut_user, name, sizeof ut.ut_user);
	gettimeofday(&ut.ut_tv, NULL);
	row(&ut);
}
Exemple #2
0
static char *
_getlogin() {
	/* find name of the controlling terminal of the calling process */
	char *tty;

	/* if the controlling terminal name cannot be determined, return a NULL pointer.
	 * `errno` will have been appropriately set by `ttyname(3)`. */
	if ((tty = ttyname(STDIN_FILENO)) == NULL)
		return NULL;

	/* the static data structure used for all calls to this function */
	static char login[GETLOGIN_LOGIN_MAX];

	utmpname(GETLOGIN_UTMP_FILE);

	/* search for an entry in the utmp file where the ut_line field matches
	 * that of the controlling terminal name */
	errno = 0;
	setutxent();
	if (errno != 0)
		return NULL;

	struct utmpx *entry, criteria;
	char *line;

	/* drop the leading slash, if any */
	if (tty[0] == '/')
		++tty;

	/* remove the `dev/` prefix from the ttyname, if existent */
	if ((line = strchr(tty, '/')) == NULL)
		line = tty;
	else
		/* dev/pts/0 becomes pts/0 */
		++line;

	strncpy(criteria.ut_line, line, __UT_LINESIZE);
	if ((entry = getutxline(&criteria)) == NULL)
		return NULL;

	strncpy(login, entry->ut_user, GETLOGIN_LOGIN_MAX);

	/* finish the reading of the utmp file */
	errno = 0;
	endutxent();
	if (errno != 0)
		return NULL;

	return login;
}
Exemple #3
0
static void logout(const char *line)
{
#ifdef HAVE_GETUTXENT
  struct utmpx utx, *putx;
  pid_t pid;

  strcpy(utx.ut_line, line);
  setutxent();
  putx = getutxline(&utx);
  if (putx != NULL)
    {
      gettimeofday(&utx.ut_tv, NULL);
      strncpy(utx.ut_line, putx->ut_line, sizeof(utx.ut_line));
      strncpy(utx.ut_user, putx->ut_name, sizeof(utx.ut_name));
      pid = getpid();
      utx.ut_pid = pid;
      strncpy(utx.ut_id, putx->ut_id, sizeof(utx.ut_id));
      utx.ut_type = DEAD_PROCESS;
      pututxline(&utx);

      updwtmpx(WTFILE, &utx);
    }
  endutxent();
#else /* HAVE_GETUTXENT */

  struct utmp utmp;
  struct utmp *putmp;
  pid_t pid;

  strcpy(utmp.ut_line, line);
  setutent();
  putmp = getutline(&utmp);
  if (putmp != NULL)
    {
      time(&utmp.ut_time);
      strncpy(utmp.ut_line, putmp->ut_line, sizeof(utmp.ut_line));
      strncpy(utmp.ut_user, putmp->ut_name, sizeof(utmp.ut_name));
      pid = getpid();
      utmp.ut_pid = pid;
      strncpy(utmp.ut_id, putmp->ut_id, sizeof(utmp.ut_id));
      utmp.ut_type = DEAD_PROCESS;
      pututline(&utmp);

      updwtmp(WTFILE, &utmp);
    }
  endutent();
#endif /* HAVE_GETUTXENT */
}
Exemple #4
0
int
logoutx(const char *line, int status, int type)
{
	struct utmpx *utp, ut;
	(void)strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
	if ((utp = getutxline(&ut)) == NULL) {
		endutxent();
		return 0;
	}
	utp->ut_type = type;
	if (WIFEXITED(status))
		utp->ut_exit.e_exit = (uint16_t)WEXITSTATUS(status);
	if (WIFSIGNALED(status))
		utp->ut_exit.e_termination = (uint16_t)WTERMSIG(status);
	(void)gettimeofday(&utp->ut_tv, NULL);
	(void)pututxline(utp);
	endutxent();
	return 1;
}
Exemple #5
0
/*
 * Records that the user has logged in.  I wish these parts of operating
 * systems were more standardized.
 */
void
record_login(pid_t pid, const char *tty, const char *user, uid_t uid,
    const char *host, struct sockaddr *addr, socklen_t addrlen)
{
#if defined(SUPPORT_UTMP) || defined(SUPPORT_UTMPX)
	int fd;
#endif
	struct timeval tv;
#ifdef SUPPORT_UTMP
	struct utmp u;
	struct lastlog ll;
#endif
#ifdef SUPPORT_UTMPX
	struct utmpx ux, *uxp = &ux;
	struct lastlogx llx;
#endif
	(void)gettimeofday(&tv, NULL);
	/*
	 * XXX: why do we need to handle logout cases here?
	 * Isn't the function below taking care of this?
	 */
	/* save previous login details before writing new */
	store_lastlog_message(user, uid);

#ifdef SUPPORT_UTMP
	/* Construct an utmp/wtmp entry. */
	memset(&u, 0, sizeof(u));
	strncpy(u.ut_line, tty + 5, sizeof(u.ut_line));
	u.ut_time = (time_t)tv.tv_sec;
	strncpy(u.ut_name, user, sizeof(u.ut_name));
	strncpy(u.ut_host, host, sizeof(u.ut_host));

	login(&u);

	/* Update lastlog unless actually recording a logout. */
	if (*user != '\0') {
		/*
		 * It is safer to memset the lastlog structure first because
		 * some systems might have some extra fields in it (e.g. SGI)
		 */
		memset(&ll, 0, sizeof(ll));

		/* Update lastlog. */
		ll.ll_time = time(NULL);
		strncpy(ll.ll_line, tty + 5, sizeof(ll.ll_line));
		strncpy(ll.ll_host, host, sizeof(ll.ll_host));
		fd = open(_PATH_LASTLOG, O_RDWR);
		if (fd >= 0) {
			lseek(fd, (off_t)uid * sizeof(ll), SEEK_SET);
			if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
				logit("Could not write %.100s: %.100s", _PATH_LASTLOG, strerror(errno));
			close(fd);
		}
	}
#endif
#ifdef SUPPORT_UTMPX
	/* Construct an utmpx/wtmpx entry. */
	memset(&ux, 0, sizeof(ux));
	strncpy(ux.ut_line, tty + 5, sizeof(ux.ut_line));
	if (*user) {
		ux.ut_pid = pid;
		ux.ut_type = USER_PROCESS;
		ux.ut_tv = tv;
		strncpy(ux.ut_name, user, sizeof(ux.ut_name));
		strncpy(ux.ut_host, host, sizeof(ux.ut_host));
		/* XXX: need ut_id, use last 4 char of tty */
		if (strlen(tty) > sizeof(ux.ut_id)) {
			strncpy(ux.ut_id,
			    tty + strlen(tty) - sizeof(ux.ut_id),
			    sizeof(ux.ut_id));
		} else
			strncpy(ux.ut_id, tty, sizeof(ux.ut_id));
		/* XXX: It would be better if we had sockaddr_storage here */
		if (addrlen > sizeof(ux.ut_ss))
			addrlen = sizeof(ux.ut_ss);
		(void)memcpy(&ux.ut_ss, addr, addrlen);
		if (pututxline(&ux) == NULL)
			logit("could not add utmpx line: %.100s",
			    strerror(errno));
		/* Update lastlog. */
		(void)gettimeofday(&llx.ll_tv, NULL);
		strncpy(llx.ll_line, tty + 5, sizeof(llx.ll_line));
		strncpy(llx.ll_host, host, sizeof(llx.ll_host));
		(void)memcpy(&llx.ll_ss, addr, addrlen);
		if (updlastlogx(_PATH_LASTLOGX, uid, &llx) == -1)
			logit("Could not update %.100s: %.100s",
			    _PATH_LASTLOGX, strerror(errno));
	} else {
		if ((uxp = getutxline(&ux)) == NULL)
			logit("could not find utmpx line for %.100s", tty);
		else {
			uxp->ut_type = DEAD_PROCESS;
			uxp->ut_tv = tv;
			/* XXX: we don't record exit info yet */
			if (pututxline(&ux) == NULL)
				logit("could not replace utmpx line: %.100s",
				    strerror(errno));
		}
	}
	endutxent();
	updwtmpx(_PATH_WTMPX, uxp);
#endif
}
Exemple #6
0
/*
 * NOT the same locate_host() in locate_host.c.  This one just does a
 * 'who am i' to try to discover where the user is...
 */
void locate_host(CtdlIPC* ipc, char *hbuf)
{
#ifndef HAVE_UTMP_H
	char buf[SIZ];
	FILE *who;
	int a,b;

	who = (FILE *)popen("who am i","r");
	if (who==NULL) {
		strcpy(hbuf, ipc->ServInfo.fqdn);
		return;	
	}
	fgets(buf,sizeof buf,who);
	pclose(who);

	b = 0;
	for (a=0; !IsEmptyStr(&buf[a]); ++a) {
		if ((buf[a]=='(')||(buf[a]==')')) ++b;
	}
	if (b<2) {
		strcpy(hbuf, ipc->ServInfo.fqdn);
		return;
	}

	for (a=0; a<strlen(buf); ++a) {
		if (buf[a]=='(') {
			strcpy(buf,&buf[a+1]);
		}
	}
	for (a=0; a<strlen(buf); ++a) {
		if (buf[a]==')') buf[a] = 0;
	}

	if (IsEmptyStr(buf)) strcpy(hbuf, ipc->ServInfo.fqdn);
	else strncpy(hbuf,buf,24);
#else
	char *tty = ttyname(0);
#ifdef HAVE_GETUTXLINE
	struct utmpx ut, *put;
#else
	struct utmp ut, *put;
#endif

	if (tty == NULL) {
	    fail:
		safestrncpy(hbuf, ipc->ServInfo.fqdn, 24);
		return;
	}

	if (strncmp(tty, "/dev/", 5))
		goto fail;

	safestrncpy(ut.ut_line, &tty[5], sizeof ut.ut_line);

#ifdef HAVE_GETUTXLINE /* Solaris uses this */
	if ((put = getutxline(&ut)) == NULL)
#else
	if ((put = getutline(&ut)) == NULL)
#endif
		goto fail;

#if defined(HAVE_UT_TYPE) || defined(HAVE_GETUTXLINE)
	if (put->ut_type == USER_PROCESS) {
#endif
#if defined(HAVE_UT_HOST) || defined(HAVE_GETUTXLINE)
		if (*put->ut_host)
			safestrncpy(hbuf, put->ut_host, 24);
		else
#endif
			safestrncpy(hbuf, put->ut_line, 24);
#if defined(HAVE_UT_TYPE) || defined(HAVE_GETUTXLINE)
	}
	else goto fail;
#endif
#endif /* HAVE_UTMP_H */
}
Exemple #7
0
void KPty::logout()
{
#ifdef HAVE_UTEMPTER
    Q_D(KPty);

    removeLineFromUtmp(d->ttyName, d->masterFd);
#else
    Q_D(KPty);

    const char *str_ptr = d->ttyName.data();
    if (!memcmp(str_ptr, "/dev/", 5)) {
        str_ptr += 5;
    }
# ifdef __GLIBC__
    else {
        const char * sl_ptr = strrchr(str_ptr, '/');
        if (sl_ptr) {
            str_ptr = sl_ptr + 1;
        }
    }
# endif
# ifdef HAVE_LOGIN
#  ifdef HAVE_LOGINX
    ::logoutx(str_ptr, 0, DEAD_PROCESS);
#  else
    ::logout(str_ptr);
#  endif
# else
#  ifdef HAVE_UTMPX
    struct utmpx l_struct, *ut;
#  else
    struct utmp l_struct, *ut;
#  endif
    memset(&l_struct, 0, sizeof(l_struct));

    strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line));

#  ifdef HAVE_UTMPX
    utmpxname(_PATH_UTMPX);
    setutxent();
    if ((ut = getutxline(&l_struct))) {
#  else
    utmpname(_PATH_UTMP);
    setutent();
    if ((ut = getutline(&l_struct))) {
#  endif
        memset(ut->ut_name, 0, sizeof(*ut->ut_name));
        memset(ut->ut_host, 0, sizeof(*ut->ut_host));
#  ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
        ut->ut_syslen = 0;
#  endif
#  ifdef HAVE_STRUCT_UTMP_UT_TYPE
        ut->ut_type = DEAD_PROCESS;
#  endif
#  ifdef HAVE_UTMPX
        gettimeofday(&ut->ut_tv, 0);
        pututxline(ut);
    }
    endutxent();
#  else
    ut->ut_time = time(0);
    pututline(ut);
}
endutent();
#  endif
# endif
#endif
}
Exemple #8
0
void
checkutmp(int picky)
{
	char *line;
	struct utmp *ut;
#if HAVE_UTMPX_H
	struct utmpx *utx;
#endif
	pid_t pid = getpid();

#if HAVE_UTMPX_H
	setutxent();
#endif
	setutent();

	if (picky) {
#if HAVE_UTMPX_H
		while ((utx = getutxent()))
			if (utx->ut_pid == pid)
				break;

		if (utx)
			utxent = *utx;
#endif
		while ((ut = getutent()))
			if (ut->ut_pid == pid)
				break;

		if (ut)
			utent = *ut;

#if HAVE_UTMPX_H
		endutxent();
#endif
		endutent();

		if (!ut) {
 			puts(NO_UTENT);
			exit(1);
		}
#ifndef	UNIXPC

		/*
		 * If there is no ut_line value in this record, fill
		 * it in by getting the TTY name and stuffing it in
		 * the structure.  The UNIX/PC is broken in this regard
		 * and needs help ...
		 */

		if (utent.ut_line[0] == '\0')
#endif	/* !UNIXPC */
		{
			if (!(line = ttyname(0))) {
				puts(NO_TTY);
				exit(1);
			}
			if (strncmp(line, "/dev/", 5) == 0)
				line += 5;
			strncpy(utent.ut_line, line, sizeof utent.ut_line);
#if HAVE_UTMPX_H
			strncpy(utxent.ut_line, line, sizeof utxent.ut_line);
#endif
		}
	} else {
		if (!(line = ttyname(0))) {
			puts(NO_TTY);
			exit(1);
		}
		if (strncmp(line, "/dev/", 5) == 0)
			line += 5;

 		strncpy (utent.ut_line, line, sizeof utent.ut_line);
		if ((ut = getutline(&utent)))
 			strncpy(utent.ut_id, ut->ut_id, sizeof ut->ut_id);

		strcpy(utent.ut_user, "LOGIN");
		utent.ut_pid = getpid();
		utent.ut_type = LOGIN_PROCESS;
		time(&utent.ut_time);
#if HAVE_UTMPX_H
		strncpy(utxent.ut_line, line, sizeof utxent.ut_line);
		if ((utx = getutxline(&utxent)))
			strncpy(utxent.ut_id, utx->ut_id, sizeof utxent.ut_id);

		strcpy(utxent.ut_user, "LOGIN");
		utxent.ut_pid = utent.ut_pid;
		utxent.ut_type = utent.ut_type;
		gettimeofday((struct timeval *) &utxent.ut_tv, NULL);
		utent.ut_time = utxent.ut_tv.tv_sec;
#endif
	}
}
Exemple #9
0
/*
 * Add or delete an entry in the system's utmp file.
 */
void
doutmp(int action, struct layer *l)
{
	/*
	 * Note that pututxline() may need privileges to work; but at least
	 * on Solaris, it does not as the libc arranges this for us. If shl
	 * has suid or sgid privileges, these are reset on startup and
	 * restored for utmp handling here.
	 */
	struct passwd *pwd = getpwuid(myuid);
	struct utmpx utx;
	char *id;

	memset(&utx, 0, sizeof utx);
	strncpy(utx.ut_line, l->l_line + 5, sizeof utx.ut_line);
	strncpy(utx.ut_user, pwd->pw_name, sizeof utx.ut_user);
	utx.ut_pid = l->l_pid;
	gettimeofday(&utx.ut_tv, NULL);
	if ((id = strrchr(l->l_line, '/')) != NULL)
		strncpy(utx.ut_id, id, sizeof utx.ut_id);
	switch (action) {
	case UTMP_ADD:
		utx.ut_type = USER_PROCESS;
		break;
	case UTMP_DEL:
		utx.ut_type = DEAD_PROCESS;
		break;
	}
	if (myuid != myeuid)
		setuid(myeuid);
	if (mygid != myegid)
		setgid(myegid);
#ifndef	__linux__
	if (action == UTMP_DEL) {
		/*
		 * On (at least) Solaris 8, /usr/lib/utmp_update will hang at
		 * ioctl(tty, TCGETA, ...) respective isatty() when the pty is
		 * in packet mode, but removing the pckt module we once pushed
		 * fails with EPERM in some circumstances (exact conditions
		 * unknown). If it does, close the pty master; pututxline()
		 * refuses to work then, but utmpd(1M) will remove the stale
		 * entry a few seconds later. This is not the ultimate
		 * solution, but better than hanging, of course. If shl needs
		 * privilegues to call pututxline(), these calls will not cause
		 * any harm since there is no dependency on the actual terminal
		 * device then.
		 */
		if (ioctl(l->l_pty, I_POP, 0) < 0) {
			close(l->l_pty);
			l->l_pty = -1;
		}
	}
#endif	/* !__linux__ */
	setutxent();
	getutxline(&utx);
	pututxline(&utx);
	endutxent();
	if (myuid != myeuid)
		setuid(myuid);
	if (mygid != myegid)
		setgid(mygid);
}
Exemple #10
0
void
utmp_logout (char *line)
{
#ifdef HAVE_UTMPX_H
  struct utmpx utx;
  struct utmpx *ut;

  strncpy (utx.ut_line, line, sizeof (utx.ut_line));

# ifdef HAVE_PUTUTXLINE
  setutxent();
  ut = getutxline (&utx);
  if (ut)
    {
      struct timeval tv;

      ut->ut_type = DEAD_PROCESS;
#  ifdef HAVE_STRUCT_UTMPX_UT_EXIT
      memset (&ut->ut_exit, 0, sizeof (ut->ut_exit));
#  endif
      gettimeofday (&tv, 0);
      ut->ut_tv.tv_sec = tv.tv_sec;
      ut->ut_tv.tv_usec = tv.tv_usec;
#  ifdef HAVE_STRUCT_UTMPX_UT_USER
      memset (&ut->ut_user, 0, sizeof (ut->ut_user));
#  elif defined HAVE_STRUCT_UTMPX_UT_NAME
      memset (&ut->ut_name, 0, sizeof (ut->ut_name));
#  endif
#  ifdef HAVE_STRUCT_UTMPX_UT_HOST
      memset (ut->ut_host, 0, sizeof (ut->ut_host));
#   ifdef HAVE_STRUCT_UTMPX_UT_SYSLEN
      ut->ut_syslen = 1;	/* Counting NUL.  */
#   endif
#  endif /* UT_HOST */
      pututxline (ut);
      /* Some systems perform wtmp updating
       * already in calling pututxline().
       */
#  ifdef HAVE_UPDWTMPX
      updwtmpx (PATH_WTMPX, ut);
#  elif defined HAVE_LOGWTMPX
      logwtmpx (ut->ut_line, "", "", 0, DEAD_PROCESS);
#  endif
    }
  endutxent ();
# elif defined HAVE_LOGOUTX /* !HAVE_PUTUTXLINE */
  if (logoutx (line, 0, DEAD_PROCESS))
    logwtmpx (line, "", "", 0, DEAD_PROCESS);
# endif /* HAVE_LOGOUTX */

#else /* !HAVE_UTMPX_H */
  struct utmp utx;
# ifdef HAVE_PUTUTLINE
  struct utmp *ut;
# endif

  strncpy (utx.ut_line, line, sizeof (utx.ut_line));

# ifdef HAVE_PUTUTLINE
  setutent();
  ut = getutline (&utx);
  if (ut)
    {
#  ifdef HAVE_STRUCT_UTMP_UT_TV
      struct timeval tv;
#  endif

#  ifdef HAVE_STRUCT_UTMP_UT_TYPE
      ut->ut_type = DEAD_PROCESS;
#  endif
#  ifdef HAVE_STRUCT_UTMP_UT_EXIT
      memset (&ut->ut_exit, 0, sizeof (ut->ut_exit));
#  endif
#  ifdef HAVE_STRUCT_UTMP_UT_TV
      gettimeofday (&tv, 0);
      ut->ut_tv.tv_sec = tv.tv_sec;
      ut->ut_tv.tv_usec = tv.tv_usec;
#  else /* !HAVE_STRUCT_UTMP_UT_TV */
      time (&(ut->ut_time));
#  endif
#  ifdef HAVE_STRUCT_UTMP_UT_USER
      memset (&ut->ut_user, 0, sizeof (ut->ut_user));
#  elif defined HAVE_STRUCT_UTMP_UT_NAME
      memset (&ut->ut_name, 0, sizeof (ut->ut_name));
#  endif
#  ifdef HAVE_STRUCT_UTMP_UT_HOST
      memset (ut->ut_host, 0, sizeof (ut->ut_host));
#  endif
      pututline (ut);
#  ifdef HAVE_UPDWTMP
      updwtmp (WTMP_FILE, ut);
#  elif defined HAVE_LOGWTMP /* !HAVE_UPDWTMP */
      logwtmp (ut->ut_line, "", "");
#  endif
    }
  endutent ();
# elif defined HAVE_LOGOUT /* !HAVE_PUTUTLINE */
  if (logout (line))
    logwtmp (line, "", "");
# endif /* HAVE_LOGOUT */
#endif
}
Exemple #11
0
/*
 * Update wtmp and utmp logs.
 */
static void log_utmp(struct login_context *cxt)
{
	struct utmpx ut;
	struct utmpx *utp;
	struct timeval tv;

	utmpxname(_PATH_UTMP);
	setutxent();

	/* Find pid in utmp.
	 *
	 * login sometimes overwrites the runlevel entry in /var/run/utmp,
	 * confusing sysvinit. I added a test for the entry type, and the
	 * problem was gone. (In a runlevel entry, st_pid is not really a pid
	 * but some number calculated from the previous and current runlevel.)
	 * -- Michael Riepe <*****@*****.**>
	 */
	while ((utp = getutxent()))
		if (utp->ut_pid == cxt->pid
		    && utp->ut_type >= INIT_PROCESS
		    && utp->ut_type <= DEAD_PROCESS)
			break;

	/* If we can't find a pre-existing entry by pid, try by line.
	 * BSD network daemons may rely on this. */
	if (utp == NULL && cxt->tty_name) {
		setutxent();
		ut.ut_type = LOGIN_PROCESS;
		str2memcpy(ut.ut_line, cxt->tty_name, sizeof(ut.ut_line));
		utp = getutxline(&ut);
	}

	/* If we can't find a pre-existing entry by pid and line, try it by id.
	 * Very stupid telnetd daemons don't set up utmp at all. (kzak) */
	if (utp == NULL && cxt->tty_number) {
	     setutxent();
	     ut.ut_type = DEAD_PROCESS;
	     str2memcpy(ut.ut_id, cxt->tty_number, sizeof(ut.ut_id));
	     utp = getutxid(&ut);
	}

	if (utp)
		memcpy(&ut, utp, sizeof(ut));
	else
		/* some gettys/telnetds don't initialize utmp... */
		memset(&ut, 0, sizeof(ut));

	if (cxt->tty_number && ut.ut_id[0] == 0)
		str2memcpy(ut.ut_id, cxt->tty_number, sizeof(ut.ut_id));
	if (cxt->username)
		str2memcpy(ut.ut_user, cxt->username, sizeof(ut.ut_user));
	if (cxt->tty_name)
		str2memcpy(ut.ut_line, cxt->tty_name, sizeof(ut.ut_line));

	gettimeofday(&tv, NULL);
	ut.ut_tv.tv_sec = tv.tv_sec;
	ut.ut_tv.tv_usec = tv.tv_usec;
	ut.ut_type = USER_PROCESS;
	ut.ut_pid = cxt->pid;
	if (cxt->hostname) {
		str2memcpy(ut.ut_host, cxt->hostname, sizeof(ut.ut_host));
		if (*cxt->hostaddress)
			memcpy(&ut.ut_addr_v6, cxt->hostaddress,
			       sizeof(ut.ut_addr_v6));
	}

	pututxline(&ut);
	endutxent();

	updwtmpx(_PATH_WTMP, &ut);
}
Exemple #12
0
static void
rmut(void)
{
    struct utmpx utmpx, *non_save_utxp;
    char *clean_tty = clean_ttyname(line);

    /*
     * This updates the utmpx and utmp entries and make a wtmp/x entry
     */

    setutxent();
    memset(&utmpx, 0, sizeof(utmpx));
    strncpy(utmpx.ut_line, clean_tty, sizeof(utmpx.ut_line));
    utmpx.ut_type = LOGIN_PROCESS;
    non_save_utxp = getutxline(&utmpx);
    if (non_save_utxp) {
	struct utmpx *utxp;
	struct timeval tv;
	char user0;

	utxp = malloc(sizeof(struct utmpx));
	*utxp = *non_save_utxp;
	user0 = utxp->ut_user[0];
	utxp->ut_user[0] = '\0';
	utxp->ut_type = DEAD_PROCESS;
#ifdef HAVE_STRUCT_UTMPX_UT_EXIT
#ifdef _STRUCT___EXIT_STATUS
	utxp->ut_exit.__e_termination = 0;
	utxp->ut_exit.__e_exit = 0;
#elif defined(__osf__) /* XXX */
	utxp->ut_exit.ut_termination = 0;
	utxp->ut_exit.ut_exit = 0;
#else
	utxp->ut_exit.e_termination = 0;
	utxp->ut_exit.e_exit = 0;
#endif
#endif
	gettimeofday (&tv, NULL);
	utxp->ut_tv.tv_sec = tv.tv_sec;
	utxp->ut_tv.tv_usec = tv.tv_usec;

	pututxline(utxp);
#ifdef WTMPX_FILE
	utxp->ut_user[0] = user0;
	updwtmpx(WTMPX_FILE, utxp);
#elif defined(WTMP_FILE)
	/* This is a strange system with a utmpx and a wtmp! */
	{
	  int f = open(wtmpf, O_WRONLY|O_APPEND);
	  struct utmp wtmp;
	  if (f >= 0) {
	    strncpy(wtmp.ut_line,  clean_tty, sizeof(wtmp.ut_line));
	    strncpy(wtmp.ut_name,  "", sizeof(wtmp.ut_name));
#ifdef HAVE_STRUCT_UTMP_UT_HOST
	    strncpy(wtmp.ut_host,  "", sizeof(wtmp.ut_host));
#endif
	    wtmp.ut_time = time(NULL);
	    write(f, &wtmp, sizeof(wtmp));
	    close(f);
	  }
	}
#endif
	free (utxp);
    }
    endutxent();
}  /* end of rmut */