Пример #1
0
static void
update_lastlog (const char *pty, const char *host)
{
# if defined(HAVE_STRUCT_LASTLOGX) && defined(HAVE_UPDLASTLOGX)
  struct lastlogx llx;
# endif
# ifdef HAVE_STRUCT_LASTLOG
  int             fd;
  struct lastlog  ll;
# endif

# if defined(HAVE_STRUCT_LASTLOGX) && defined(HAVE_UPDLASTLOGX)
  memset (&llx, 0, sizeof (llx));
  llx.ll_tv.tv_sec = time (NULL);
  llx.ll_tv.tv_usec = 0;
  strncpy (llx.ll_line, pty, sizeof (llx.ll_line));
  strncpy (llx.ll_host, host, sizeof (llx.ll_host));
  updlastlogx (LASTLOGX_FILE, getuid (), &llx);
# endif

# ifdef HAVE_STRUCT_LASTLOG
  memset (&ll, 0, sizeof (ll));
  ll.ll_time = time (NULL);
  strncpy (ll.ll_line, pty, sizeof (ll.ll_line));
  strncpy (ll.ll_host, host, sizeof (ll.ll_host));
  if ((fd = open (LASTLOG_FILE, O_RDWR)) != -1)
    {
      if (lseek (fd, (off_t) (getuid () * sizeof (ll)),
                 SEEK_SET) != -1)
        write (fd, &ll, sizeof (ll));
      close (fd);
    }
# endif /* HAVE_STRUCT_LASTLOG */
}
Пример #2
0
static void
dolastlogx(int quiet)
{
	struct lastlogx ll;
	if (!quiet && getlastlogx(_PATH_LASTLOGX, pwd->pw_uid, &ll) != NULL) {
		time_t t = (time_t)ll.ll_tv.tv_sec;
		(void)printf("Last login: %.24s ", ctime(&t));
		if (*ll.ll_host != '\0')
			(void)printf("from %.*s ",
			    (int)sizeof(ll.ll_host),
			    ll.ll_host);
		(void)printf("on %.*s\n",
		    (int)sizeof(ll.ll_line),
		    ll.ll_line);
	}
	ll.ll_tv = now;
	(void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
	if (hostname)
		(void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
	else
		(void)memset(ll.ll_host, '\0', sizeof(ll.ll_host));
	if (have_ss)
		ll.ll_ss = ss;
	else
		(void)memset(&ll.ll_ss, 0, sizeof(ll.ll_ss));
	if (updlastlogx(_PATH_LASTLOGX, pwd->pw_uid, &ll) != 0)
		syslog(LOG_NOTICE, "Cannot update lastlogx: %m");
}
Пример #3
0
static void
update_lastlog (const char *fname, const char *pty, const char *host)
{
# if defined(HAVE_STRUCT_LASTLOGX) && defined(HAVE_UPDLASTLOGX)
  struct lastlogx llx;
# endif
# ifdef HAVE_STRUCT_LASTLOG
  int             fd;
  struct lastlog  ll;
  char            lastlogfile[256];
  struct passwd  *pwent;
  struct stat     st;
# endif

# if defined(HAVE_STRUCT_LASTLOGX) && defined(HAVE_UPDLASTLOGX)
  memset (&llx, 0, sizeof (llx));
  llx.ll_tv.tv_sec = time (NULL);
  llx.ll_tv.tv_usec = 0;
  strncpy (llx.ll_line, pty, sizeof (llx.ll_line));
  strncpy (llx.ll_host, host, sizeof (llx.ll_host));
  updlastlogx (LASTLOGX_FILE, getuid (), &llx);
# endif

# ifdef HAVE_STRUCT_LASTLOG
  pwent = getpwuid (getuid ());
  if (!pwent)
    {
      ptytty_warn ("no entry in password file, not updating lastlog.\n", 0);
      return;
    }

  memset (&ll, 0, sizeof (ll));
  ll.ll_time = time (NULL);
  strncpy (ll.ll_line, pty, sizeof (ll.ll_line));
  strncpy (ll.ll_host, host, sizeof (ll.ll_host));
  if (stat (fname, &st) != 0)
    return;
  if (S_ISDIR (st.st_mode))
    {
      snprintf (lastlogfile, sizeof (lastlogfile), "%s/%s", fname,
               (!pwent->pw_name || pwent->pw_name[0] == '\0') ? "unknown"
               : pwent->pw_name);
      if ((fd = open (lastlogfile, O_WRONLY | O_CREAT, 0644)) >= 0)
        {
          write (fd, &ll, sizeof (ll));
          close (fd);
        }
    }
  else if (S_ISREG (st.st_mode))
    if ((fd = open (fname, O_RDWR)) != -1)
      {
        if (lseek (fd, (off_t) ((long)pwent->pw_uid * sizeof (ll)),
                   SEEK_SET) != -1)
          write (fd, &ll, sizeof (ll));
        close (fd);
      }
# endif /* HAVE_STRUCT_LASTLOG */
}
Пример #4
0
/* INTPROTO */
static void
rxvt_update_lastlog(const char *fname, const char *pty, const char *host)
{
# ifdef HAVE_STRUCT_LASTLOGX
    struct lastlogx llx;
# endif
# ifdef HAVE_STRUCT_LASTLOG
    int             fd;
    struct lastlog  ll;
#  ifdef LASTLOG_IS_DIR
    char            lastlogfile[256];
#  endif
    struct passwd  *pwent;
# endif

# ifdef HAVE_STRUCT_LASTLOGX
    MEMSET(&llx, 0, sizeof(llx));
    llx.ll_tv.tv_sec = time(NULL);
    llx.ll_tv.tv_usec = 0;
    STRNCPY(llx.ll_line, pty, sizeof(llx.ll_line));
    STRNCPY(llx.ll_host, host, sizeof(llx.ll_host));
    updlastlogx(RXVT_LASTLOGX_FILE, getuid(), &llx);
# endif

# ifdef HAVE_STRUCT_LASTLOG
    pwent = getpwuid(getuid());
    if (!pwent) {
	rxvt_msg (DBG_ERROR, DBG_LOGGING, "no entry in password file");
	return;
    }
    MEMSET(&ll, 0, sizeof(ll));
    ll.ll_time = time(NULL);
    STRNCPY(ll.ll_line, pty, sizeof(ll.ll_line));
    STRNCPY(ll.ll_host, host, sizeof(ll.ll_host));
#  ifdef LASTLOG_IS_DIR
    sprintf(lastlogfile, "%.*s/%.*s",
        sizeof(lastlogfile) - sizeof(pwent->pw_name) - 2, fname,
        sizeof(pwent->pw_name),
        (!pwent->pw_name || pwent->pw_name[0] == '\0') ? "unknown"
			       : pwent->pw_name);
    if ((fd = open(lastlogfile, O_WRONLY | O_CREAT, 0644)) >= 0) {
	write(fd, &ll, sizeof(ll));
	close(fd);
    }
#  else
    if ((fd = open(fname, O_RDWR)) != -1) {
	if (lseek(fd, (off_t) ((long)pwent->pw_uid * sizeof(ll)),
	      SEEK_SET) != -1)
	    write(fd, &ll, sizeof(ll));
	close(fd);
    }
#  endif	    /* LASTLOG_IS_DIR */
# endif		    /* HAVE_STRUCT_LASTLOG */
}
Пример #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
}
Пример #6
0
struct utmpx *
pututxline(const struct utmpx *utx)
{
	struct passwd *pw;
	struct lastlogx ll;
	struct utmpx temp, *u = NULL;
	int gotlock = 0;

	_DIAGASSERT(utx != NULL);

	if (utx == NULL)
		return NULL;

	if (utx->ut_type == USER_PROCESS) {
		ll.ll_tv = utx->ut_tv;
		strcpy(ll.ll_host, utx->ut_host);
		strcpy(ll.ll_line, utx->ut_line);
		pw = getpwnam(utx->ut_name);
		if (pw != NULL)
			updlastlogx(_PATH_LASTLOGX, pw->pw_uid, &ll);
	}

	if (strcmp(_PATH_UTMPX, utfile) == 0)
		if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0))
			return utmp_update(utx);


	(void)memcpy(&temp, utx, sizeof(temp));

	if (fp == NULL) {
		(void)getutxent();
		if (fp == NULL || readonly)
			return NULL;
	}

	if (getutxid(&temp) == NULL) {
		setutxent();
		if (getutxid(&temp) == NULL) {
			if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1)
				return NULL;
			gotlock++;
			if (fseeko(fp, (off_t)0, SEEK_END) == -1)
				goto fail;
		}
	}

	if (!gotlock) {
		/* we are not appending */
		if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1)
			return NULL;
	}

	if (fwrite(&temp, sizeof (temp), 1, fp) != 1)
		goto fail;

	if (fflush(fp) == -1)
		goto fail;

	u = memcpy(&ut, &temp, sizeof(ut));
fail:
	if (gotlock) {
		if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
			return NULL;
	}
	return u;
}