/* * 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) { struct logininfo *li; /* save previous login details before writing new */ store_lastlog_message(user, uid); li = login_alloc_entry(pid, user, host, tty); login_set_addr(li, addr, addrlen); login_login(li); login_free_entry(li); }
/* * 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) { int fd; struct lastlog ll; char *lastlog; struct utmp u; /* save previous login details before writing new */ store_lastlog_message(user, uid); /* Construct an utmp/wtmp entry. */ memset(&u, 0, sizeof(u)); strncpy(u.ut_line, tty + 5, sizeof(u.ut_line)); u.ut_time = time(NULL); strncpy(u.ut_name, user, sizeof(u.ut_name)); strncpy(u.ut_host, host, sizeof(u.ut_host)); login(&u); lastlog = _PATH_LASTLOG; /* Update lastlog unless actually recording a logout. */ if (strcmp(user, "") != 0) { /* * It is safer to bzero 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(lastlog, O_RDWR); if (fd >= 0) { lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) logit("Could not write %.100s: %.100s", lastlog, strerror(errno)); close(fd); } } }
/* * 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 }