Пример #1
0
static void cleanup_utmp(void)
{
    struct timeval tv;

    if (!pty_stamped_utmp)
	return;

    utmp_entry.ut_type = DEAD_PROCESS;
    memset(utmp_entry.ut_user, 0, lenof(utmp_entry.ut_user));
    gettimeofday(&tv, NULL);
    utmp_entry.ut_tv.tv_sec = tv.tv_sec;
    utmp_entry.ut_tv.tv_usec = tv.tv_usec;

    updwtmpx(WTMPX_FILE, &utmp_entry);

    memset(utmp_entry.ut_line, 0, lenof(utmp_entry.ut_line));
    utmp_entry.ut_tv.tv_sec = 0;
    utmp_entry.ut_tv.tv_usec = 0;

    setutxent();
    pututxline(&utmp_entry);
    endutxent();

    pty_stamped_utmp = 0;	       /* ensure we never double-cleanup */
}
Пример #2
0
/*
 * Logs failed login attempts in _PATH_BTMP, if it exists.
 * Must be called only with username the name of an actual user.
 * The most common login failure is to give password instead of username.
 */
static void log_btmp(struct login_context *cxt)
{
	struct utmpx ut;
	struct timeval tv;

	memset(&ut, 0, sizeof(ut));

	str2memcpy(ut.ut_user,
		cxt->username ? cxt->username : "******",
		sizeof(ut.ut_user));

	if (cxt->tty_number)
		str2memcpy(ut.ut_id, cxt->tty_number, sizeof(ut.ut_id));
	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 = LOGIN_PROCESS;	/* XXX doesn't matter */
	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));
	}

	updwtmpx(_PATH_BTMP, &ut);
}
Пример #3
0
static void
doutmpx(void)
{
	struct utmpx utmpx;
	char *t;

	memset((void *)&utmpx, 0, sizeof(utmpx));
	utmpx.ut_tv = now;
	(void)strncpy(utmpx.ut_name, username, sizeof(utmpx.ut_name));
	if (hostname) {
		(void)strncpy(utmpx.ut_host, hostname, sizeof(utmpx.ut_host));
		utmpx.ut_ss = ss;
	}
	(void)strncpy(utmpx.ut_line, tty, sizeof(utmpx.ut_line));
	utmpx.ut_type = USER_PROCESS;
	utmpx.ut_pid = getpid();
	t = tty + strlen(tty);
	if (t - tty >= sizeof(utmpx.ut_id)) {
	    (void)strncpy(utmpx.ut_id, t - sizeof(utmpx.ut_id),
		sizeof(utmpx.ut_id));
	} else {
	    (void)strncpy(utmpx.ut_id, tty, sizeof(utmpx.ut_id));
	}
	if (pututxline(&utmpx) == NULL)
		syslog(LOG_NOTICE, "Cannot update utmpx: %m");
	endutxent();
	if (updwtmpx(_PATH_WTMPX, &utmpx) != 0)
		syslog(LOG_NOTICE, "Cannot update wtmpx: %m");
}
Пример #4
0
static void remove_utmp_entry(main_server_st *s, struct proc_st* proc)
{
#ifdef HAVE_LIBUTIL
	struct utmpx entry;
	struct timespec tv;

	if (s->config->use_utmp == 0)
		return;

	memset(&entry, 0, sizeof(entry));
	entry.ut_type = DEAD_PROCESS;
	if (proc->tun_lease.name[0] != 0)
		snprintf(entry.ut_line, sizeof(entry.ut_line), "%s", proc->tun_lease.name);
	entry.ut_pid = proc->pid;

	setutxent();
	pututxline(&entry);
	endutxent();

#if defined(WTMPX_FILE)
	gettime(&tv);
	entry.ut_tv.tv_sec = tv.tv_sec;
	entry.ut_tv.tv_usec = tv.tv_nsec / 1000;
	updwtmpx(WTMPX_FILE, &entry);
#endif   
	return;
#endif
}
Пример #5
0
/* This is a slight modification of code in OpenBSD's logwtmp.c */
static int
wtmpx_write(struct logininfo *li, struct utmpx *utx)
{
#ifndef HAVE_UPDWTMPX
	struct stat buf;
	int fd, ret = 1;

	if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) {
		logit("wtmpx_write: problem opening %s: %s",
		    WTMPX_FILE, strerror(errno));
		return 0;
	}

	if (fstat(fd, &buf) == 0)
		if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) {
			ftruncate(fd, buf.st_size);
			logit("wtmpx_write: problem writing %s: %s",
			    WTMPX_FILE, strerror(errno));
			ret = 0;
		}
	(void)close(fd);

	return ret;
#else
	updwtmpx(WTMPX_FILE, utx);
	return 1;
#endif
}
Пример #6
0
void
utmpx_mark_dead(pid_t pid, int status, boolean_t blocking)
{
	struct utmpx *up;
	int logged = 0;

	for (;;) {
		int found = 0;

		MUTEX_LOCK(&utmpx_lock);
		setutxent();

		while (up = getutxent()) {
			if (up->ut_pid == pid) {
				found = 1;

				if (up->ut_type == DEAD_PROCESS) {
					/*
					 * Cleaned up elsewhere.
					 */
					endutxent();
					MUTEX_UNLOCK(&utmpx_lock);
					return;
				}

				up->ut_type = DEAD_PROCESS;
				up->ut_exit.e_termination = WTERMSIG(status);
				up->ut_exit.e_exit = WEXITSTATUS(status);
				(void) time(&up->ut_tv.tv_sec);

				if (pututxline(up) != NULL) {
					/*
					 * Now attempt to add to the end of the
					 * wtmp and wtmpx files.  Do not create
					 * if they don't already exist.
					 */
					updwtmpx(WTMPX_FILE, up);
					endutxent();
					MUTEX_UNLOCK(&utmpx_lock);

					return;
				}
			}
		}

		endutxent();
		MUTEX_UNLOCK(&utmpx_lock);

		if (!found || !blocking)
			return;

		if (!logged) {
			log_framework(LOG_INFO, "retrying utmpx_dead on PID "
			    "%ld\n", pid);
			logged++;
		}

		(void) sleep(1);
	}
}
Пример #7
0
Файл: dm.c Проект: mit-athena/dm
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 */
}
Пример #8
0
static void
utmpx_write_entry(short type, const char *msg, time_t tstamp)
{
	struct utmpx u;
	struct utmpx *oup;
	size_t tmplen;

	bzero(&u, sizeof (struct utmpx));

	u.ut_id[0] = u.ut_id[1] = u.ut_id[2] = u.ut_id[3] = '\0';
	u.ut_pid = 0;

	u.ut_exit.e_termination = WTERMSIG(0);
	u.ut_exit.e_exit = WEXITSTATUS(0);
	u.ut_type = type;
	u.ut_tv.tv_sec = tstamp;

	MUTEX_LOCK(&utmpx_lock);
	setutxent();

	if ((oup = getutxid(&u)) != NULL) {
		bcopy(oup->ut_user, u.ut_user, sizeof (u.ut_user));
		bcopy(oup->ut_line, u.ut_line, sizeof (u.ut_line));
		bcopy(oup->ut_host, u.ut_host, sizeof (u.ut_host));

		tmplen = strlen(u.ut_host);
		if (tmplen)
			u.ut_syslen = min(tmplen + 1, sizeof (u.ut_host));
		else
			u.ut_syslen =  0;
	}

	(void) sprintf(u.ut_line, "%.12s", msg);

	if (pututxline(&u) == NULL) {
		endutxent();
		MUTEX_UNLOCK(&utmpx_lock);

		return;
	}

	updwtmpx(WTMPX_FILE, &u);

	endutxent();
	MUTEX_UNLOCK(&utmpx_lock);

	utmpx_check();
}
Пример #9
0
/*
 * setutmpx - the UTMPX version for setutmp
 */
int setutmpx (struct utmpx *utx)
{
	int err = 0;

	assert (NULL != utx);

	setutxent ();
	if (pututxline (utx) == NULL) {
		err = 1;
	}
	endutxent ();

	updwtmpx (_WTMP_FILE "x", utx);

	return err;
}
Пример #10
0
int
main(int argc, char **argv)
{
	struct utmpx *utmpx;

	setutxent();
	while ((utmpx = getutxent()) != NULL) {
		if (utmpx->ut_type == USER_PROCESS) {
			utmpx->ut_type = DEAD_PROCESS;
			time(&utmpx->ut_xtime);
			(void) updwtmpx(WTMPX_FILE, utmpx);
		}
	}
	endutxent();
	return (0);
}
Пример #11
0
static void setup_utmp(char *ttyname, char *location)
{
#ifdef HAVE_LASTLOG
    struct lastlog lastlog_entry;
    FILE *lastlog;
#endif
    struct passwd *pw;
    struct timeval tv;

    pw = getpwuid(getuid());
    memset(&utmp_entry, 0, sizeof(utmp_entry));
    utmp_entry.ut_type = USER_PROCESS;
    utmp_entry.ut_pid = getpid();
    strncpy(utmp_entry.ut_line, ttyname+5, lenof(utmp_entry.ut_line));
    strncpy(utmp_entry.ut_id, ttyname+8, lenof(utmp_entry.ut_id));
    strncpy(utmp_entry.ut_user, pw->pw_name, lenof(utmp_entry.ut_user));
    strncpy(utmp_entry.ut_host, location, lenof(utmp_entry.ut_host));
    /*
     * Apparently there are some architectures where (struct
     * utmpx).ut_tv is not essentially struct timeval (e.g. Linux
     * amd64). Hence the temporary.
     */
    gettimeofday(&tv, NULL);
    utmp_entry.ut_tv.tv_sec = tv.tv_sec;
    utmp_entry.ut_tv.tv_usec = tv.tv_usec;

    setutxent();
    pututxline(&utmp_entry);
    endutxent();

    updwtmpx(WTMPX_FILE, &utmp_entry);

#ifdef HAVE_LASTLOG
    memset(&lastlog_entry, 0, sizeof(lastlog_entry));
    strncpy(lastlog_entry.ll_line, ttyname+5, lenof(lastlog_entry.ll_line));
    strncpy(lastlog_entry.ll_host, location, lenof(lastlog_entry.ll_host));
    time(&lastlog_entry.ll_time);
    if ((lastlog = fopen(LASTLOG_FILE, "r+")) != NULL) {
	fseek(lastlog, sizeof(lastlog_entry) * getuid(), SEEK_SET);
	fwrite(&lastlog_entry, 1, sizeof(lastlog_entry), lastlog);
	fclose(lastlog);
    }
#endif

    pty_stamped_utmp = 1;

}
Пример #12
0
static void write_wtmp(void)
{
	struct utmpx utmp;
	struct utsname uts;
	/* "man utmp" says wtmp file should *not* be created automagically */
	/*if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) {
		close(creat(bb_path_wtmp_file, 0664));
	}*/
	memset(&utmp, 0, sizeof(utmp));
	utmp.ut_tv.tv_sec = time(NULL);
	strcpy(utmp.ut_user, "shutdown"); /* it is wide enough */
	utmp.ut_type = RUN_LVL;
	utmp.ut_id[0] = '~'; utmp.ut_id[1] = '~'; /* = strcpy(utmp.ut_id, "~~"); */
	utmp.ut_line[0] = '~'; utmp.ut_line[1] = '~'; /* = strcpy(utmp.ut_line, "~~"); */
	uname(&uts);
	safe_strncpy(utmp.ut_host, uts.release, sizeof(utmp.ut_host));
	updwtmpx(bb_path_wtmp_file, &utmp);
}
Пример #13
0
void
vsf_remove_uwtmp(void)
{
  if (!s_uwtmp_inserted)
  {
    return;
  }
  s_uwtmp_inserted = 0;
  s_utent.ut_type = DEAD_PROCESS;
  vsf_sysutil_memclr(s_utent.ut_user, sizeof(s_utent.ut_user));
  vsf_sysutil_memclr(s_utent.ut_host, sizeof(s_utent.ut_host));
  s_utent.ut_tv.tv_sec = 0;
  setutxent();
  (void) pututxline(&s_utent);
  endutxent();
  s_utent.ut_tv.tv_sec = vsf_sysutil_get_time_sec();
  updwtmpx(WTMPX_FILE, &s_utent);
}
Пример #14
0
static void
_login(const struct utmpx *ut) {
	struct utmpx record;
	strncpy(record.ut_user, ut->ut_user, __UT_NAMESIZE);

	/* fill in basic information */
	record.ut_type = USER_PROCESS;
	record.ut_pid  = getpid();

	int stds[] = { STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO },
		i;
	char *tty;

	/* iterate over stdin, stdout and stderr (in that order), trying to find the
	 * name of the controlling terminal of the calling process. */
	for (i = 0; i < 2; ++i) {
		if ((tty = ttyname(stds[1])) != NULL)
			break;
	}

	if (tty != NULL) {
		/* strip leading slash if any */
		if (tty[0] == '/')
			++tty;

		char *p;
		/* remove `dev/` prefix */
		if ((p = strchr(tty, '/')) != NULL)
			tty = p + 1;

		strncpy(record.ut_line, tty, __UT_LINESIZE);
	}

	/* commit the record to the utmp file */
	if (pututxline(&record) == NULL)
		pexit("pututxline");

	/* commit the record to the wtmp file */
	updwtmpx(wtmp_file, &record);
}
Пример #15
0
void
vsf_insert_uwtmp(const struct mystr* p_user_str,
                 const struct mystr* p_host_str)
{
  if (sizeof(s_utent.ut_line) < 16)
  {
    return;
  }
  if (s_uwtmp_inserted)
  {
    bug("vsf_insert_uwtmp");
  }
  {
    struct mystr line_str = INIT_MYSTR;
    str_alloc_text(&line_str, VSF_PROJECT ":");
    str_append_ulong(&line_str, vsf_sysutil_getpid());
    if (str_getlen(&line_str) >= sizeof(s_utent.ut_line))
    {
      str_free(&line_str);
      return;
    }
    vsf_sysutil_strcpy(s_utent.ut_line, str_getbuf(&line_str),
                       sizeof(s_utent.ut_line));
    str_free(&line_str);
  }
  s_uwtmp_inserted = 1;
  s_utent.ut_type = USER_PROCESS;
  s_utent.ut_pid = vsf_sysutil_getpid();
  vsf_sysutil_strcpy(s_utent.ut_user, str_getbuf(p_user_str),
                     sizeof(s_utent.ut_user));
  vsf_sysutil_strcpy(s_utent.ut_host, str_getbuf(p_host_str),
                     sizeof(s_utent.ut_host));
  s_utent.ut_tv.tv_sec = vsf_sysutil_get_time_sec();
  setutxent();
  (void) pututxline(&s_utent);
  endutxent();
#ifdef VSF_SYSDEP_HAVE_UPDWTMPX
  updwtmpx(WTMPX_FILE, &s_utent);
#endif
}
Пример #16
0
void
logwtmpx(const char *line, const char *name, const char *host, int status,
    int type)
{
	struct utmpx ut;

	_DIAGASSERT(line != NULL);
	_DIAGASSERT(name != NULL);
	_DIAGASSERT(host != NULL);

	(void)memset(&ut, 0, sizeof(ut));
	(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
	(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
	(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
	ut.ut_type = type;
	if (WIFEXITED(status))
		ut.ut_exit.e_exit = (uint16_t)WEXITSTATUS(status);
	if (WIFSIGNALED(status))
		ut.ut_exit.e_termination = (uint16_t)WTERMSIG(status);
	(void)gettimeofday(&ut.ut_tv, NULL);
	(void)updwtmpx(_PATH_WTMPX, &ut);
}
Пример #17
0
static void
add_utmp_entry(main_server_st *s, struct proc_st* proc)
{
#ifdef HAVE_LIBUTIL
	struct utmpx entry;
	struct timespec tv;
	
	if (s->config->use_utmp == 0)
		return;

	memset(&entry, 0, sizeof(entry));
	entry.ut_type = USER_PROCESS;
	entry.ut_pid = proc->pid;
	snprintf(entry.ut_line, sizeof(entry.ut_line), "%s", proc->tun_lease.name);
	snprintf(entry.ut_user, sizeof(entry.ut_user), "%s", proc->username);
#ifdef __linux__
	if (proc->remote_addr_len == sizeof(struct sockaddr_in))
		memcpy(entry.ut_addr_v6, SA_IN_P(&proc->remote_addr), sizeof(struct in_addr));
	else
		memcpy(entry.ut_addr_v6, SA_IN6_P(&proc->remote_addr), sizeof(struct in6_addr));
#endif

	gettime(&tv);
	entry.ut_tv.tv_sec = tv.tv_sec;
	entry.ut_tv.tv_usec = tv.tv_nsec / 1000;
	getnameinfo((void*)&proc->remote_addr, proc->remote_addr_len, entry.ut_host, sizeof(entry.ut_host), NULL, 0, NI_NUMERICHOST);

	setutxent();
	pututxline(&entry);
	endutxent();

#if defined(WTMPX_FILE)
	updwtmpx(WTMPX_FILE, &entry);
#endif   
	
	return;
#endif
}
Пример #18
0
static void
utmpx_update(struct utmpx *ut, char *line, const char *user, const char *host)
{
    struct timeval tmp;
    char *clean_tty = clean_ttyname(line);

    strncpy(ut->ut_line, clean_tty, sizeof(ut->ut_line));
#ifdef HAVE_STRUCT_UTMPX_UT_ID
    strncpy(ut->ut_id, make_id(clean_tty), sizeof(ut->ut_id));
#endif
    strncpy(ut->ut_user, user, sizeof(ut->ut_user));
    shrink_hostname (host, ut->ut_host, sizeof(ut->ut_host));
#ifdef HAVE_STRUCT_UTMPX_UT_SYSLEN
    ut->ut_syslen = strlen(host) + 1;
    if (ut->ut_syslen > sizeof(ut->ut_host))
        ut->ut_syslen = sizeof(ut->ut_host);
#endif
    ut->ut_type = USER_PROCESS;
    gettimeofday (&tmp, 0);
    ut->ut_tv.tv_sec = tmp.tv_sec;
    ut->ut_tv.tv_usec = tmp.tv_usec;
    pututxline(ut);
#ifdef WTMPX_FILE
    updwtmpx(WTMPX_FILE, ut);
#elif defined(WTMP_FILE)
    { /* XXX should be removed, just drop wtmp support */
	struct utmp utmp;
	int fd;

	prepare_utmp (&utmp, line, user, host);
	if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
	    write(fd, &utmp, sizeof(struct utmp));
	    close(fd);
	}
    }
#endif
}
int
main(int argc, char *argv[])
{
    struct utmpx ut;
    char *devName;

    if (argc < 2 || strcmp(argv[1], "--help") == 0)
        usageErr("%s username [sleep-time]\n", argv[0]);

    /* Initialize login record for utmp and wtmp files */

    memset(&ut, 0, sizeof(struct utmpx));
    ut.ut_type = USER_PROCESS;          /* This is a user login */
    strncpy(ut.ut_user, argv[1], sizeof(ut.ut_user));
    if (time((time_t *) &ut.ut_tv.tv_sec) == -1)
        errExit("time");                /* Stamp with current time */
    ut.ut_pid = getpid();

    /* Set ut_line and ut_id based on the terminal associated with
       'stdin'. This code assumes terminals named "/dev/[pt]t[sy]*".
       The "/dev/" dirname is 5 characters; the "[pt]t[sy]" filename
       prefix is 3 characters (making 8 characters in all). */

    devName = ttyname(STDIN_FILENO);
    if (devName == NULL)
        errExit("ttyname");
    if (strlen(devName) <= 8)           /* Should never happen */
        fatal("Terminal name is too short: %s", devName);

    strncpy(ut.ut_line, devName + 5, sizeof(ut.ut_line));
    strncpy(ut.ut_id, devName + 8, sizeof(ut.ut_id));

    printf("Creating login entries in utmp and wtmp\n");
    printf("        using pid %ld, line %.*s, id %.*s\n",
            (long) ut.ut_pid, (int) sizeof(ut.ut_line), ut.ut_line,
            (int) sizeof(ut.ut_id), ut.ut_id);

    setutxent();                        /* Rewind to start of utmp file */
    if (pututxline(&ut) == NULL)        /* Write login record to utmp */
        errExit("pututxline");
    updwtmpx(_PATH_WTMP, &ut);          /* Append login record to wtmp */

    /* Sleep a while, so we can examine utmp and wtmp files */

    sleep((argc > 2) ? getInt(argv[2], GN_NONNEG, "sleep-time") : 15);

    /* Now do a "logout"; use values from previously initialized 'ut',
       except for changes below */

    ut.ut_type = DEAD_PROCESS;          /* Required for logout record */
    time((time_t *) &ut.ut_tv.tv_sec);  /* Stamp with logout time */
    memset(&ut.ut_user, 0, sizeof(ut.ut_user));
                                        /* Logout record has null username */

    printf("Creating logout entries in utmp and wtmp\n");
    setutxent();                        /* Rewind to start of utmp file */
    if (pututxline(&ut) == NULL)        /* Overwrite previous utmp record */
        errExit("pututxline");
    updwtmpx(_PATH_WTMP, &ut);          /* Append logout record to wtmp */

    endutxent();
    exit(EXIT_SUCCESS);
}
Пример #20
0
/*
 * make and write utmp and wtmp entries
 */
void
ptytty_unix::login (int cmd_pid, bool login_shell, const char *hostname)
{
  const char *pty = name;

  if (!pty || !*pty)
    return;

  this->cmd_pid     = cmd_pid;
  this->login_shell = login_shell;

#ifdef HAVE_STRUCT_UTMP
  struct utmp *ut = &this->ut;
#endif
#ifdef HAVE_STRUCT_UTMPX
  struct utmpx *utx = &this->utx;
#endif
  int i;
  struct passwd *pwent = getpwuid (getuid ());
  const char *name = (pwent && pwent->pw_name) ? pwent->pw_name : "?";

  if (!strncmp (pty, "/dev/", 5))
    pty += 5;		/* skip /dev/ prefix */

#if defined(HAVE_UTMP_PID) || defined(HAVE_STRUCT_UTMPX)
  if (!strncmp (pty, "pty", 3) || !strncmp (pty, "tty", 3))
    strncpy (ut_id, pty + 3, sizeof (ut_id));
  else if (sscanf (pty, "pts/%d", &i) == 1)
    sprintf (ut_id, "vt%02x", (i & 0xff));	/* sysv naming */
  else
    {
      ptytty_warn ("can't parse tty name \"%s\", not adding utmp entry.\n", pty);
      return;
    }
#endif

#ifdef HAVE_STRUCT_UTMP
  memset (ut, 0, sizeof (struct utmp));
# ifdef HAVE_UTMP_PID
  setutent ();
  strncpy (ut->ut_id, ut_id, sizeof (ut->ut_id));
  ut->ut_type = DEAD_PROCESS;
  getutid (ut);		/* position to entry in utmp file */
# endif
#endif

#ifdef HAVE_STRUCT_UTMPX
  memset (utx, 0, sizeof (struct utmpx));
  setutxent ();
  strncpy (utx->ut_id, ut_id, sizeof (utx->ut_id));
  utx->ut_type = DEAD_PROCESS;
  getutxid (utx);		/* position to entry in utmp file */
#endif

#ifdef HAVE_STRUCT_UTMP
  strncpy (ut->ut_line, pty, sizeof (ut->ut_line));
# ifdef HAVE_UTMP_HOST
  strncpy (ut->ut_host, hostname, sizeof (ut->ut_host));
# endif
  ut->ut_time = time (NULL);
# ifdef HAVE_UTMP_PID
  strncpy (ut->ut_user, name, sizeof (ut->ut_user));
  strncpy (ut->ut_id, ut_id, sizeof (ut->ut_id));
  ut->ut_pid = cmd_pid;
  ut->ut_type = USER_PROCESS;
  pututline (ut);
  endutent ();			/* close the file */
  utmp_pos = 0;
# else
  strncpy (ut->ut_name, name, sizeof (ut->ut_name));
# endif
#endif

#ifdef HAVE_STRUCT_UTMPX
  strncpy (utx->ut_line, pty, sizeof (utx->ut_line));
  strncpy (utx->ut_user, name, sizeof (utx->ut_user));
  strncpy (utx->ut_id, ut_id, sizeof (utx->ut_id));
# if HAVE_UTMPX_SESSION
  utx->ut_session = getsid (0);
# endif
  utx->ut_tv.tv_sec = time (NULL);
  utx->ut_tv.tv_usec = 0;
  utx->ut_pid = cmd_pid;
# ifdef HAVE_UTMPX_HOST
  strncpy (utx->ut_host, hostname, sizeof (utx->ut_host));
#  if 0
  {
    char           *colon;

    if ((colon = strrchr (ut->ut_host, ':')) != NULL)
      *colon = '\0';
  }
#  endif
# endif
  utx->ut_type = USER_PROCESS;
  pututxline (utx);
  endutxent ();		/* close the file */
  utmp_pos = 0;
#endif

#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
  {
# if 1
    int fdstdin = dup (STDIN_FILENO);
    dup2 (tty, STDIN_FILENO);

    i = ttyslot ();
    if (write_bsd_utmp (i, ut))
      utmp_pos = i;

    dup2 (fdstdin, STDIN_FILENO);
    close (fdstdin);
# endif
  }
#endif

#ifdef WTMP_SUPPORT
#ifdef LOG_ONLY_ON_LOGIN
  if (login_shell)
#endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
      updwtmp (WTMP_FILE, ut);
#  else
      update_wtmp (WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && defined(HAVE_UPDWTMPX)
      updwtmpx (WTMPX_FILE, utx);
# endif
    }
#endif
#if defined(LASTLOG_SUPPORT) && defined(LASTLOG_FILE)
#ifdef LOG_ONLY_ON_LOGIN
  if (login_shell)
#endif
    update_lastlog (LASTLOG_FILE, pty, hostname);
#endif
}
Пример #21
0
/*
 * remove utmp and wtmp entries
 */
void
ptytty_unix::logout ()
{
  if (!cmd_pid)
    return;

#ifdef HAVE_STRUCT_UTMP
  struct utmp *tmput, *ut = &this->ut;
#endif
#ifdef HAVE_STRUCT_UTMPX
  struct utmpx *tmputx, *utx = &this->utx;
#endif

#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
  memset (ut, 0, sizeof (struct utmp));
  setutent ();
  strncpy (ut->ut_id, this->ut_id, sizeof (ut->ut_id));
  ut->ut_type = USER_PROCESS;
  if ((tmput = getutid (ut)))		/* position to entry in utmp file */
    ut = tmput;
  ut->ut_type = DEAD_PROCESS;
# else
  memset (ut->ut_name, 0, sizeof (ut->ut_name));
#  ifdef HAVE_UTMP_HOST
  memset (ut->ut_host, 0, sizeof (ut->ut_host));
#  endif
# endif
  ut->ut_time = time (NULL);
#endif

#ifdef HAVE_STRUCT_UTMPX
  memset (utx, 0, sizeof (struct utmpx));
  setutxent ();
  strncpy (utx->ut_id, this->ut_id, sizeof (utx->ut_id));
  utx->ut_type = USER_PROCESS;
  if ((tmputx = getutxid (utx)))	/* position to entry in utmp file */
    utx = tmputx;
  utx->ut_type = DEAD_PROCESS;
# if HAVE_UTMPX_SESSION
  utx->ut_session = getsid (0);
# endif
  utx->ut_tv.tv_sec = time (NULL);
  utx->ut_tv.tv_usec = 0;
#endif

  /*
   * Write ending wtmp entry
   */
#ifdef WTMP_SUPPORT
#ifdef LOG_ONLY_ON_LOGIN
  if (login_shell)
#endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
      updwtmp (WTMP_FILE, ut);
#  else
      update_wtmp (WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && defined(HAVE_UPDWTMPX)
      updwtmpx (WTMPX_FILE, utx);
# endif
    }
#endif

  /*
   * Write utmp entry
   */
#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
  if (ut->ut_pid == cmd_pid)
    pututline (ut);
  endutent ();
# else
  memset (ut, 0, sizeof (struct utmp));
  write_bsd_utmp (utmp_pos, ut);
# endif
#endif
#ifdef HAVE_STRUCT_UTMPX
  if (utx->ut_pid == cmd_pid)
    pututxline (utx);
  endutxent ();
#endif

  cmd_pid = 0;
}
Пример #22
0
void
setutmp(const char *name, const char *line, const char *host)
{
	struct	utmp	*utmp, utline;
	struct	utmpx	*utmpx, utxline;
	pid_t	pid = getpid ();
	int	found_utmpx = 0, found_utmp = 0;

	/*
	 * The canonical device name doesn't include "/dev/"; skip it
	 * if it is already there.
	 */

	if (strncmp (line, "/dev/", 5) == 0)
		line += 5;

	/*
	 * Update utmpx.  We create an empty entry in case there is
	 * no matching entry in the utmpx file.
	 */

	setutxent ();
	setutent ();

	while (utmpx = getutxent ()) {
		if (utmpx->ut_pid == pid) {
			found_utmpx = 1;
			break;
		}
	}
	while (utmp = getutent ()) {
		if (utmp->ut_pid == pid) {
			found_utmp = 1;
			break;
		}
	}

	/*
	 * If the entry matching `pid' cannot be found, create a new
	 * entry with the device name in it.
	 */

	if (! found_utmpx) {
		memset ((void *) &utxline, 0, sizeof utxline);
		strncpy (utxline.ut_line, line, sizeof utxline.ut_line);
		utxline.ut_pid = getpid ();
	} else {
		utxline = *utmpx;
		if (strncmp (utxline.ut_line, "/dev/", 5) == 0) {
			memmove (utxline.ut_line, utxline.ut_line + 5,
				sizeof utxline.ut_line - 5);
			utxline.ut_line[sizeof utxline.ut_line - 5] = '\0';
		}
	}
	if (! found_utmp) {
		memset ((void *) &utline, 0, sizeof utline);
		strncpy (utline.ut_line, utxline.ut_line,
			sizeof utline.ut_line);
		utline.ut_pid = utxline.ut_pid;
	} else {
		utline = *utmp;
		if (strncmp (utline.ut_line, "/dev/", 5) == 0) {
			memmove (utline.ut_line, utline.ut_line + 5,
				sizeof utline.ut_line - 5);
			utline.ut_line[sizeof utline.ut_line - 5] = '\0';
		}
	}

	/*
	 * Fill in the fields in the utmpx entry and write it out.  Do
	 * the utmp entry at the same time to make sure things don't
	 * get messed up.
	 */

	strncpy (utxline.ut_user, name, sizeof utxline.ut_user);
	strncpy (utline.ut_user, name, sizeof utline.ut_user);

	utline.ut_type = utxline.ut_type = USER_PROCESS;

	gettimeofday(&utxline.ut_tv, NULL);
	utline.ut_time = utxline.ut_tv.tv_sec;

	strncpy(utxline.ut_host, host ? host : "", sizeof utxline.ut_host);

	pututxline (&utxline);
	pututline (&utline);

	updwtmpx(_WTMP_FILE "x", &utxline);
	updwtmp(_WTMP_FILE, &utline);

	utxent = utxline;
	utent = utline;
}
Пример #23
0
int
step_systime(
	double step
	)
{
	time_t pivot; /* for ntp era unfolding */
	struct timeval timetv, tvlast, tvdiff;
	struct timespec timets;
	struct calendar jd;
	l_fp fp_ofs, fp_sys; /* offset and target system time in FP */

	/*
	 * Get pivot time for NTP era unfolding. Since we don't step
	 * very often, we can afford to do the whole calculation from
	 * scratch. And we're not in the time-critical path yet.
	 */
#if SIZEOF_TIME_T > 4
	/*
	 * This code makes sure the resulting time stamp for the new
	 * system time is in the 2^32 seconds starting at 1970-01-01,
	 * 00:00:00 UTC.
	 */
	pivot = 0x80000000;
#if USE_COMPILETIME_PIVOT
	/*
	 * Add the compile time minus 10 years to get a possible target
	 * area of (compile time - 10 years) to (compile time + 126
	 * years).  This should be sufficient for a given binary of
	 * NTPD.
	 */
	if (ntpcal_get_build_date(&jd)) {
		jd.year -= 10;
		pivot += ntpcal_date_to_time(&jd);
	} else {
		msyslog(LOG_ERR,
			"step-systime: assume 1970-01-01 as build date");
	}
#else
	UNUSED_LOCAL(jd);
#endif /* USE_COMPILETIME_PIVOT */
#else
	UNUSED_LOCAL(jd);
	/* This makes sure the resulting time stamp is on or after
	 * 1969-12-31/23:59:59 UTC and gives us additional two years,
	 * from the change of NTP era in 2036 to the UNIX rollover in
	 * 2038. (Minus one second, but that won't hurt.) We *really*
	 * need a longer 'time_t' after that!  Or a different baseline,
	 * but that would cause other serious trouble, too.
	 */
	pivot = 0x7FFFFFFF;
#endif

	/* get the complete jump distance as l_fp */
	DTOLFP(sys_residual, &fp_sys);
	DTOLFP(step,         &fp_ofs);
	L_ADD(&fp_ofs, &fp_sys);

	/* ---> time-critical path starts ---> */

	/* get the current time as l_fp (without fuzz) and as struct timeval */
	get_ostime(&timets);
	fp_sys = tspec_stamp_to_lfp(timets);
	tvlast.tv_sec = timets.tv_sec;
	tvlast.tv_usec = (timets.tv_nsec + 500) / 1000;

	/* get the target time as l_fp */
	L_ADD(&fp_sys, &fp_ofs);

	/* unfold the new system time */
	timetv = lfp_stamp_to_tval(fp_sys, &pivot);

	/* now set new system time */
	if (ntp_set_tod(&timetv, NULL) != 0) {
		msyslog(LOG_ERR, "step-systime: %m");
		return FALSE;
	}

	/* <--- time-critical path ended with 'ntp_set_tod()' <--- */

	sys_residual = 0;
	lamport_violated = (step < 0);
	if (step_callback)
		(*step_callback)();

#ifdef NEED_HPUX_ADJTIME
	/*
	 * CHECKME: is this correct when called by ntpdate?????
	 */
	_clear_adjtime();
#endif

	/*
	 * FreeBSD, for example, has:
	 * struct utmp {
	 *	   char    ut_line[UT_LINESIZE];
	 *	   char    ut_name[UT_NAMESIZE];
	 *	   char    ut_host[UT_HOSTSIZE];
	 *	   long    ut_time;
	 * };
	 * and appends line="|", name="date", host="", time for the OLD
	 * and appends line="{", name="date", host="", time for the NEW
	 * to _PATH_WTMP .
	 *
	 * Some OSes have utmp, some have utmpx.
	 */

	/*
	 * Write old and new time entries in utmp and wtmp if step
	 * adjustment is greater than one second.
	 *
	 * This might become even Uglier...
	 */
	tvdiff = abs_tval(sub_tval(timetv, tvlast));
	if (tvdiff.tv_sec > 0) {
#ifdef HAVE_UTMP_H
		struct utmp ut;
#endif
#ifdef HAVE_UTMPX_H
		struct utmpx utx;
#endif

#ifdef HAVE_UTMP_H
		ZERO(ut);
#endif
#ifdef HAVE_UTMPX_H
		ZERO(utx);
#endif

		/* UTMP */

#ifdef UPDATE_UTMP
# ifdef HAVE_PUTUTLINE
#  ifndef _PATH_UTMP
#   define _PATH_UTMP UTMP_FILE
#  endif
		utmpname(_PATH_UTMP);
		ut.ut_type = OLD_TIME;
		strlcpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line));
		ut.ut_time = tvlast.tv_sec;
		setutent();
		pututline(&ut);
		ut.ut_type = NEW_TIME;
		strlcpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line));
		ut.ut_time = timetv.tv_sec;
		setutent();
		pututline(&ut);
		endutent();
# else /* not HAVE_PUTUTLINE */
# endif /* not HAVE_PUTUTLINE */
#endif /* UPDATE_UTMP */

		/* UTMPX */

#ifdef UPDATE_UTMPX
# ifdef HAVE_PUTUTXLINE
		utx.ut_type = OLD_TIME;
		strlcpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line));
		utx.ut_tv = tvlast;
		setutxent();
		pututxline(&utx);
		utx.ut_type = NEW_TIME;
		strlcpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line));
		utx.ut_tv = timetv;
		setutxent();
		pututxline(&utx);
		endutxent();
# else /* not HAVE_PUTUTXLINE */
# endif /* not HAVE_PUTUTXLINE */
#endif /* UPDATE_UTMPX */

		/* WTMP */

#ifdef UPDATE_WTMP
# ifdef HAVE_PUTUTLINE
#  ifndef _PATH_WTMP
#   define _PATH_WTMP WTMP_FILE
#  endif
		utmpname(_PATH_WTMP);
		ut.ut_type = OLD_TIME;
		strlcpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line));
		ut.ut_time = tvlast.tv_sec;
		setutent();
		pututline(&ut);
		ut.ut_type = NEW_TIME;
		strlcpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line));
		ut.ut_time = timetv.tv_sec;
		setutent();
		pututline(&ut);
		endutent();
# else /* not HAVE_PUTUTLINE */
# endif /* not HAVE_PUTUTLINE */
#endif /* UPDATE_WTMP */

		/* WTMPX */

#ifdef UPDATE_WTMPX
# ifdef HAVE_PUTUTXLINE
		utx.ut_type = OLD_TIME;
		utx.ut_tv = tvlast;
		strlcpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line));
#  ifdef HAVE_UPDWTMPX
		updwtmpx(WTMPX_FILE, &utx);
#  else /* not HAVE_UPDWTMPX */
#  endif /* not HAVE_UPDWTMPX */
# else /* not HAVE_PUTUTXLINE */
# endif /* not HAVE_PUTUTXLINE */
# ifdef HAVE_PUTUTXLINE
		utx.ut_type = NEW_TIME;
		utx.ut_tv = timetv;
		strlcpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line));
#  ifdef HAVE_UPDWTMPX
		updwtmpx(WTMPX_FILE, &utx);
#  else /* not HAVE_UPDWTMPX */
#  endif /* not HAVE_UPDWTMPX */
# else /* not HAVE_PUTUTXLINE */
# endif /* not HAVE_PUTUTXLINE */
#endif /* UPDATE_WTMPX */

	}
	return TRUE;
}
Пример #24
0
static void
updateXtmp_unix (TimeInternal oldTime, TimeInternal newTime)
{

/* Add the old time entry to utmp/wtmp */

/* About as long as the ntpd implementation, but not any less ugly */

#ifdef HAVE_UTMPX_H
		struct utmpx utx;
	memset(&utx, 0, sizeof(utx));
		strncpy(utx.ut_user, "date", sizeof(utx.ut_user));
#ifndef OTIME_MSG
		strncpy(utx.ut_line, "|", sizeof(utx.ut_line));
#else
		strncpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line));
#endif /* OTIME_MSG */
#ifdef OLD_TIME
		utx.ut_tv.tv_sec = oldTime.seconds;
		utx.ut_tv.tv_usec = oldTime.nanoseconds / 1000;
		utx.ut_type = OLD_TIME;
#else /* no ut_type */
		utx.ut_time = oldTime.seconds;
#endif /* OLD_TIME */

/* ======== BEGIN  OLD TIME EVENT - UTMPX / WTMPX =========== */
#ifdef HAVE_UTMPXNAME
		utmpxname("/var/log/utmp");
#endif /* HAVE_UTMPXNAME */
		setutxent();
		pututxline(&utx);
		endutxent();
#ifdef HAVE_UPDWTMPX
		updwtmpx("/var/log/wtmp", &utx);
#endif /* HAVE_IPDWTMPX */
/* ======== END    OLD TIME EVENT - UTMPX / WTMPX =========== */

#else /* NO UTMPX_H */

#ifdef HAVE_UTMP_H
		struct utmp ut;
		memset(&ut, 0, sizeof(ut));
		strncpy(ut.ut_name, "date", sizeof(ut.ut_name));
#ifndef OTIME_MSG
		strncpy(ut.ut_line, "|", sizeof(ut.ut_line));
#else
		strncpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line));
#endif /* OTIME_MSG */

#ifdef OLD_TIME

#ifdef HAVE_STRUCT_UTMP_UT_TIME
		ut.ut_time = oldTime.seconds;
#else
		ut.ut_tv.tv_sec = oldTime.seconds;
		ut.ut_tv.tv_usec = oldTime.nanoseconds / 1000;
#endif /* HAVE_STRUCT_UTMP_UT_TIME */

		ut.ut_type = OLD_TIME;
#else /* no ut_type */
		ut.ut_time = oldTime.seconds;
#endif /* OLD_TIME */

/* ======== BEGIN  OLD TIME EVENT - UTMP / WTMP =========== */
#ifdef HAVE_UTMPNAME
		utmpname(UTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
#ifdef HAVE_UTMPNAME
		utmpname(WTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
/* ======== END    OLD TIME EVENT - UTMP / WTMP =========== */

#endif /* HAVE_UTMP_H */
#endif /* HAVE_UTMPX_H */

/* Add the new time entry to utmp/wtmp */

#ifdef HAVE_UTMPX_H
		memset(&utx, 0, sizeof(utx));
		strncpy(utx.ut_user, "date", sizeof(utx.ut_user));
#ifndef NTIME_MSG
		strncpy(utx.ut_line, "{", sizeof(utx.ut_line));
#else
		strncpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line));
#endif /* NTIME_MSG */
#ifdef NEW_TIME
		utx.ut_tv.tv_sec = newTime.seconds;
		utx.ut_tv.tv_usec = newTime.nanoseconds / 1000;
		utx.ut_type = NEW_TIME;
#else /* no ut_type */
		utx.ut_time = newTime.seconds;
#endif /* NEW_TIME */

/* ======== BEGIN  NEW TIME EVENT - UTMPX / WTMPX =========== */
#ifdef HAVE_UTMPXNAME
		utmpxname("/var/log/utmp");
#endif /* HAVE_UTMPXNAME */
		setutxent();
		pututxline(&utx);
		endutxent();
#ifdef HAVE_UPDWTMPX
		updwtmpx("/var/log/wtmp", &utx);
#endif /* HAVE_UPDWTMPX */
/* ======== END    NEW TIME EVENT - UTMPX / WTMPX =========== */

#else /* NO UTMPX_H */

#ifdef HAVE_UTMP_H
		memset(&ut, 0, sizeof(ut));
		strncpy(ut.ut_name, "date", sizeof(ut.ut_name));
#ifndef NTIME_MSG
		strncpy(ut.ut_line, "{", sizeof(ut.ut_line));
#else
		strncpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line));
#endif /* NTIME_MSG */
#ifdef NEW_TIME

#ifdef HAVE_STRUCT_UTMP_UT_TIME
		ut.ut_time = newTime.seconds;
#else
		ut.ut_tv.tv_sec = newTime.seconds;
		ut.ut_tv.tv_usec = newTime.nanoseconds / 1000;
#endif /* HAVE_STRUCT_UTMP_UT_TIME */
		ut.ut_type = NEW_TIME;
#else /* no ut_type */
		ut.ut_time = newTime.seconds;
#endif /* NEW_TIME */

/* ======== BEGIN  NEW TIME EVENT - UTMP / WTMP =========== */
#ifdef HAVE_UTMPNAME
		utmpname(UTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
#ifdef HAVE_UTMPNAME
		utmpname(WTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
/* ======== END    NEW TIME EVENT - UTMP / WTMP =========== */

#endif /* HAVE_UTMP_H */
#endif /* HAVE_UTMPX_H */

}
Пример #25
0
/* EXTPROTO */
void
rxvt_cleanutent(rxvt_t *r)
{
#ifdef UTEMPTER_SUPPORT
    utempter_remove_record (PVTS(r)->cmd_fd);
#else	/* UTEMPTER_SUPPORT */

#ifdef HAVE_STRUCT_UTMP
    struct utmp    *ut = &(PVTS(r)->ut);
#endif
#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    struct utmpx   *tmputx, *utx = &(PVTS(r)->utx);
#endif

#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
    MEMSET(ut, 0, sizeof(struct utmp));
    setutent();
    STRNCPY(ut->ut_id, PVTS(r)->ut_id, sizeof(ut->ut_id));
    ut->ut_type = USER_PROCESS;
    {
	struct utmp    *tmput = getutid(ut);

	if (tmput)	/* position to entry in utmp file */
	    ut = tmput;
    }
    ut->ut_type = DEAD_PROCESS;
# else 
    MEMSET(ut->ut_name, 0, sizeof(ut->ut_name));
#  ifdef HAVE_UTMP_HOST
    MEMSET(ut->ut_host, 0, sizeof(ut->ut_host));
#  endif
# endif
    ut->ut_time = time(NULL);
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    MEMSET(utx, 0, sizeof(struct utmpx));
    setutxent();
    STRNCPY(utx->ut_id, PVTS(r)->ut_id, sizeof(utx->ut_id));
    utx->ut_type = USER_PROCESS;
    if ((tmputx = getutxid(utx)))   /* position to entry in utmp file */
	utx = tmputx;
    utx->ut_type = DEAD_PROCESS;
# ifdef HAVE_UTMPX_SESSION
    utx->ut_session = getsid(0);
# endif
    utx->ut_tv.tv_sec = time(NULL);
    utx->ut_tv.tv_usec = 0;
#endif

    /*
     * Write ending wtmp entry
     */
#ifdef WTMP_SUPPORT
# ifdef WTMP_ONLY_ON_LOGIN
    if (ISSET_OPTION(r, Opt_loginShell))
# endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
	updwtmp(RXVT_WTMP_FILE, ut);
#  else
	rxvt_update_wtmp(RXVT_WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
#  ifdef HAVE_UPDWTMPX
	updwtmpx(RXVT_WTMPX_FILE, utx);
#  else
	pututxline (utx);
#  endif
# endif
    }
#endif

    /*
     * Write utmp entry
     */
#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
    if (ut->ut_pid == PVTS(r)->cmd_pid)
	pututline(ut);
    endutent();
# else
    MEMSET(ut, 0, sizeof(struct utmp));
    rxvt_write_bsd_utmp(PVTS(r)->utmp_pos, ut);
# endif
#endif
#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    if (utx->ut_pid == PVTS(r)->cmd_pid)
	pututxline(utx);
    endutxent();
#endif

#endif	/* UTEMPTER_SUPPORT */
}
Пример #26
0
int
setdate(struct tm *current_date, char *date)
{
	int	i;
	int	mm;
	int	hh;
	int	min;
	int	sec = 0;
	char	*secptr;
	int	yy;
	int	dd	= 0;
	int	minidx	= 6;
	int	len;
	int	dd_check;

	/*  Parse date string  */
	if ((secptr = strchr(date, '.')) != NULL && strlen(&secptr[1]) == 2 &&
	    isdigit(secptr[1]) && isdigit(secptr[2]) &&
	    (sec = atoi(&secptr[1])) >= 0 && sec < 60)
		secptr[0] = '\0';	/* eat decimal point only on success */

	len = strlen(date);

	for (i = 0; i < len; i++) {
		if (!isdigit(date[i])) {
			(void) fprintf(stderr,
			gettext("date: bad conversion\n"));
			exit(1);
		}
	}
	switch (strlen(date)) {
	case 12:
		yy = atoi(&date[8]);
		date[8] = '\0';
		break;
	case 10:
		/*
		 * The YY format has the following representation:
		 * 00-68 = 2000 thru 2068
		 * 69-99 = 1969 thru 1999
		 */
		if (atoi(&date[8]) <= 68) {
			yy = 1900 + (atoi(&date[8]) + 100);
		} else {
			yy = 1900 + atoi(&date[8]);
		}
		date[8] = '\0';
		break;
	case 8:
		yy = 1900 + current_date->tm_year;
		break;
	case 4:
		yy = 1900 + current_date->tm_year;
		mm = current_date->tm_mon + 1; 	/* tm_mon goes from 1 to 11 */
		dd = current_date->tm_mday;
		minidx = 2;
		break;
	default:
		(void) fprintf(stderr, gettext("date: bad conversion\n"));
		return (1);
	}

	min = atoi(&date[minidx]);
	date[minidx] = '\0';
	hh = atoi(&date[minidx-2]);
	date[minidx-2] = '\0';

	if (!dd) {
		/*
		 * if dd is 0 (not between 1 and 31), then
		 * read the value supplied by the user.
		 */
		dd = atoi(&date[2]);
		date[2] = '\0';
		mm = atoi(&date[0]);
	}

	if (hh == 24)
		hh = 0, dd++;

	/*  Validate date elements  */
	dd_check = 0;
	if (mm >= 1 && mm <= 12) {
		dd_check = month_size[mm - 1];	/* get days in this month */
		if (mm == 2 && isleap(yy))	/* adjust for leap year */
			dd_check++;
	}
	if (!((mm >= 1 && mm <= 12) && (dd >= 1 && dd <= dd_check) &&
	    (hh >= 0 && hh <= 23) && (min >= 0 && min <= 59))) {
		(void) fprintf(stderr, gettext("date: bad conversion\n"));
		return (1);
	}

	/*  Build date and time number  */
	for (clock_val = 0, i = 1970; i < yy; i++)
		clock_val += year_size(i);
	/*  Adjust for leap year  */
	if (isleap(yy) && mm >= 3)
		clock_val += 1;
	/*  Adjust for different month lengths  */
	while (--mm)
		clock_val += (time_t)month_size[mm - 1];
	/*  Load up the rest  */
	clock_val += (time_t)(dd - 1);
	clock_val *= 24;
	clock_val += (time_t)hh;
	clock_val *= 60;
	clock_val += (time_t)min;
	clock_val *= 60;
	clock_val += sec;

	if (!uflag) {
		/* convert to GMT assuming standard time */
		/* correction is made in localtime(3C) */

		/*
		 * call localtime to set up "timezone" variable applicable
		 * for clock_val time, to support Olson timezones which
		 * can allow timezone rules to change.
		 */
		(void) localtime(&clock_val);

		clock_val += (time_t)timezone;

		/* correct if daylight savings time in effect */

		if (localtime(&clock_val)->tm_isdst)
			clock_val = clock_val - (time_t)(timezone - altzone);
	}

	(void) time(&wtmpx[0].ut_xtime);
	if (stime(&clock_val) < 0) {
		perror("date");
		return (1);
	}
#if defined(i386)
	/* correct the kernel's "gmt_lag" and the PC's RTC */
	(void) system("/usr/sbin/rtc -c > /dev/null 2>&1");
#endif
	(void) time(&wtmpx[1].ut_xtime);
	(void) pututxline(&wtmpx[0]);
	(void) pututxline(&wtmpx[1]);
	(void) updwtmpx(WTMPX_FILE, &wtmpx[0]);
	(void) updwtmpx(WTMPX_FILE, &wtmpx[1]);
	return (0);
}
Пример #27
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
}
Пример #28
0
void KPty::login(const char * user, const char * remotehost)
{
#ifdef HAVE_UTEMPTER
    Q_D(KPty);

    addToUtmp(d->ttyName, remotehost, d->masterFd);
    Q_UNUSED(user);
#else
# ifdef HAVE_UTMPX
    struct utmpx l_struct;
# else
    struct utmp l_struct;
# endif
    memset(&l_struct, 0, sizeof(l_struct));
    // note: strncpy without terminators _is_ correct here. man 4 utmp

    if (user) {
        strncpy(l_struct.ut_name, user, sizeof(l_struct.ut_name));
    }

    if (remotehost) {
        strncpy(l_struct.ut_host, remotehost, sizeof(l_struct.ut_host));
# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
        l_struct.ut_syslen = qMin(strlen(remotehost), sizeof(l_struct.ut_host));
# endif
    }

# ifndef __GLIBC__
    Q_D(KPty);
    const char * str_ptr = d->ttyName.data();
    if (!memcmp(str_ptr, "/dev/", 5)) {
        str_ptr += 5;
    }
    strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line));
#  ifdef HAVE_STRUCT_UTMP_UT_ID
    strncpy(l_struct.ut_id,
            str_ptr + strlen(str_ptr) - sizeof(l_struct.ut_id),
            sizeof(l_struct.ut_id));
#  endif
# endif

# ifdef HAVE_UTMPX
    gettimeofday(&l_struct.ut_tv, 0);
# else
    l_struct.ut_time = time(0);
# endif

# ifdef HAVE_LOGIN
#  ifdef HAVE_LOGINX
    ::loginx(&l_struct);
#  else
    ::login(&l_struct);
#  endif
# else
#  ifdef HAVE_STRUCT_UTMP_UT_TYPE
    l_struct.ut_type = USER_PROCESS;
#  endif
#  ifdef HAVE_STRUCT_UTMP_UT_PID
    l_struct.ut_pid = getpid();
#   ifdef HAVE_STRUCT_UTMP_UT_SESSION
    l_struct.ut_session = getsid(0);
#   endif
#  endif
#  ifdef HAVE_UTMPX
    utmpxname(_PATH_UTMPX);
    setutxent();
    pututxline(&l_struct);
    endutxent();
#   ifdef HAVE_UPDWTMPX
    updwtmpx(_PATH_WTMPX, &l_struct);
#   endif
#  else
    utmpname(_PATH_UTMP);
    setutent();
    pututline(&l_struct);
    endutent();
    updwtmp(_PATH_WTMP, &l_struct);
#  endif
# endif
#endif
}
Пример #29
0
/* EXTPROTO */
void
rxvt_makeutent(rxvt_t *r, const char *pty, const char *hostname)
{
#ifdef UTEMPTER_SUPPORT
    utempter_add_record (PVTS(r)->cmd_fd, hostname);
#else	/* UTEMPTER_SUPPORT */

#ifdef HAVE_STRUCT_UTMP
    struct utmp    *ut = &(PVTS(r)->ut);
#endif
#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    struct utmpx   *utx = &(PVTS(r)->utx);
#endif
#ifdef HAVE_UTMP_PID
    int             i;
#endif
    char            ut_id[5];
    struct passwd  *pwent = getpwuid(getuid());

    if (!STRNCMP(pty, "/dev/", 5))
	pty += 5;	/* skip /dev/ prefix */

    if (!STRNCMP(pty, "pty", 3) || !STRNCMP(pty, "tty", 3)) {
	STRNCPY(ut_id, (pty + 3), sizeof(ut_id));
    }
#ifdef HAVE_UTMP_PID
    else if (sscanf(pty, "pts/%d", &i) == 1)
	sprintf(ut_id, "vt%02x", (i & 0xff));	/* sysv naming */
#endif
    else if (STRNCMP(pty, "pty", 3) && STRNCMP(pty, "tty", 3)) {
	rxvt_msg (DBG_ERROR, DBG_LOGGING, "can't parse tty name \"%s\"", pty);
	return;
    }

#ifdef HAVE_STRUCT_UTMP
    MEMSET(ut, 0, sizeof(struct utmp));
# ifdef HAVE_UTMP_PID
    setutent();
    STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id));
    ut->ut_type = DEAD_PROCESS;
    getutid(ut);	/* position to entry in utmp file */
    STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id));
# endif
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    MEMSET(utx, 0, sizeof(struct utmpx));
    setutxent();
    STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id));
    utx->ut_type = DEAD_PROCESS;
    getutxid(utx);	/* position to entry in utmp file */
    STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id));
#endif

#ifdef HAVE_STRUCT_UTMP
    STRNCPY(ut->ut_line, pty, sizeof(ut->ut_line));
    ut->ut_time = time(NULL);
# ifdef HAVE_UTMP_PID
    STRNCPY(ut->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(ut->ut_user));
    STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id));
    ut->ut_time = time(NULL);
    ut->ut_pid = PVTS(r)->cmd_pid;
#  ifdef HAVE_UTMP_HOST
    STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host));
#  endif
    ut->ut_type = USER_PROCESS;
    pututline(ut);
    endutent();		/* close the file */
    PVTS(r)->utmp_pos = 0;
# else
    STRNCPY(ut->ut_name, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(ut->ut_name));
#  ifdef HAVE_UTMP_HOST
    STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host));
#  endif
# endif
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    STRNCPY(utx->ut_line, pty, sizeof(utx->ut_line));
    STRNCPY(utx->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(utx->ut_user));
    STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id));
# ifdef HAVE_UTMPX_SESSION
    utx->ut_session = getsid(0);
# endif
    utx->ut_tv.tv_sec = time(NULL);
    utx->ut_tv.tv_usec = 0;
    utx->ut_pid = PVTS(r)->cmd_pid;
# ifdef HAVE_UTMPX_HOST
    STRNCPY(utx->ut_host, hostname, sizeof(utx->ut_host));
# endif
    utx->ut_type = USER_PROCESS;
    pututxline(utx);
    endutxent();	/* close the file */
    PVTS(r)->utmp_pos = 0;
#endif

#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
    {
	int             i;
# ifdef HAVE_TTYSLOT
	i = ttyslot();
	if (rxvt_write_bsd_utmp(i, ut))
	    PVTS(r)->utmp_pos = i;
# else
	FILE           *fd0;

	if (NOT_NULL(fd0 = fopen(TTYTAB_FILENAME, "r"))) {
	    char            buf[256], name[256];

	    buf[sizeof(buf) - 1] = '\0';
	    for (i = 1; NOT_NULL(fgets(buf, sizeof(buf) - 1, fd0)); ) {
		if (*buf == '#' || sscanf(buf, "%s", name) != 1)
		    continue;
		if (!STRCMP(ut->ut_line, name)) {
		    if (!rxvt_write_bsd_utmp(i, ut))
			i = 0;
		    PVTS(r)->utmp_pos = i;
		    fclose(fd0);
		    break;
		}
		i++;
	    }
	    fclose(fd0);
	}
# endif
    }
#endif

#ifdef WTMP_SUPPORT
# ifdef WTMP_ONLY_ON_LOGIN
    if (ISSET_OPTION(r, Opt_loginShell))
# endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
	updwtmp(RXVT_WTMP_FILE, ut);
#  else
	rxvt_update_wtmp(RXVT_WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
#  ifdef HAVE_UPDWTMPX
	updwtmpx(RXVT_WTMPX_FILE, utx);
#  else
	pututxline (utx);
#  endif
# endif
    }
#endif

#endif	/* UTEMPTER_SUPPORT */

#if defined(LASTLOG_SUPPORT) && defined(RXVT_LASTLOG_FILE)
    if (ISSET_OPTION(r, Opt_loginShell))
	rxvt_update_lastlog(RXVT_LASTLOG_FILE, pty, hostname);
#endif

}
Пример #30
0
static int
psr_set_state(processorid_t cpu, int action, psr_action_t *pac, int mustexist)
{
	int	old_state;
	int	err;
	time_t	now;
	char	buf[80];

	old_state = p_online(cpu, P_STATUS);
	if (old_state < 0) {
		if (errno == EINVAL && !mustexist)
			return (0);	/* no such processor */
		err = errno;		/* in case sprintf smashes errno */
		(void) snprintf(buf, sizeof (buf), "%s: processor %d",
		    cmdname, cpu);
		errno = err;
		perror(buf);
		return (-1);
	}

	if (old_state == P_FAULTED && action != P_FAULTED && !force) {
		(void) printf("%s: processor %d in faulted state; "
		    "add -F option to force change\n", cmdname, cpu);
		return (-1);
	}

	old_state = p_online(cpu, force ? action | P_FORCED : action);
	if (old_state < 0) {
		if (errno == EINVAL && !mustexist)
			return (0);	/* no such processor */
		err = errno;
		(void) snprintf(buf, sizeof (buf), "%s: processor %d",
		    cmdname, cpu);
		errno = err;
		perror(buf);
		return (-1);
	}
	if (old_state == action) {
		if (verbose)
			(void) printf("processor %d already %s.\n", cpu,
			    pac->p_state);
		return (1);		/* no change */
	}

	(void) snprintf(buf, sizeof (buf), "processor %d %s %s.",
	    cpu, pac->p_action, pac->p_state);

	if (verbose)
		(void) printf("%s\n", buf);

	/*
	 * Log the change.
	 */
	if (!log_open) {
		log_open = 1;
		openlog(cmdname, LOG_CONS, LOG_USER);	/* open syslog */
		(void) setlogmask(LOG_UPTO(LOG_INFO));

		ut.ut_pid = getpid();
		ut.ut_type = USER_PROCESS;
		(void) strncpy(ut.ut_user, "psradm", sizeof (ut.ut_user) - 1);
	}

	syslog(LOG_INFO, "%s", buf);

	/*
	 * Update wtmp.
	 */
	(void) snprintf(ut.ut_line, sizeof (ut.ut_line), PSRADM_MSG,
	    cpu, pac->p_wtmp);
	(void) time(&now);
	ut.ut_xtime = now;
	updwtmpx(WTMPX_FILE, &ut);

	return (1);	/* the processor exists and no errors occurred */
}