/* * change the system date on the master */ static void mchgdate(struct tsp *msg) { char tname[MAXHOSTNAMELEN]; char olddate[32]; struct timeval otime, ntime; strlcpy(tname, msg->tsp_name, sizeof(tname)); xmit(TSP_DATEACK, msg->tsp_seq, &from); strlcpy(olddate, date(), sizeof(olddate)); /* adjust time for residence on the queue */ gettimeofday(&otime, 0); adj_msg_time(msg,&otime); timevalsub(&ntime, &msg->tsp_time, &otime); if (ntime.tv_sec < MAXADJ && ntime.tv_sec > -MAXADJ) { /* * do not change the clock if we can adjust it */ dictate = 3; synch(tvtomsround(ntime)); } else { logwtmp("|", "date", ""); settimeofday(&msg->tsp_time, 0); logwtmp("{", "date", ""); spreadtime(); } syslog(LOG_NOTICE, "date changed by %s from %s", tname, olddate); }
/*ARGSUSED*/ #endif /* !defined TSP_SETDATE */ static void reset(const time_t newt, const int nflag) { register const char * username; static struct timeval tv; /* static so tv_usec is 0 */ #ifdef EBUG return; #endif /* defined EBUG */ username = getlogin(); if (username == NULL || *username == '\0') /* single-user or no tty */ username = "******"; tv.tv_sec = newt; #ifdef TSP_SETDATE if (nflag || !netsettime(tv)) #endif /* defined TSP_SETDATE */ { /* ** "old" entry is always written, for compatibility. */ logwtmp("|", TIME_NAME, ""); if (settimeofday(&tv, NULL) == 0) { logwtmp("{", TIME_NAME, ""); /* } */ syslog(LOG_AUTH | LOG_NOTICE, _("date set by %s"), username); } else oops("settimeofday"); } }
/* ARGSUSED */ void cleanup(int sig) { char *p, c; p = line + sizeof(_PATH_DEV) - 1; #ifdef SUPPORT_UTMP if (logout(p)) logwtmp(p, "", ""); #endif #ifdef SUPPORT_UTMPX if (logoutx(p, 0, DEAD_PROCESS)) logwtmpx(p, "", "", 0, DEAD_PROCESS); #endif (void)chmod(line, 0666); (void)chown(line, 0, 0); c = *p; *p = 'p'; (void)chmod(line, 0666); (void)chown(line, 0, 0); *p = c; if (ttyaction(line, "telnetd", "root")) syslog(LOG_ERR, "%s: ttyaction failed", line); (void) shutdown(net, 2); exit(1); }
void cleanup(int sig) { #if defined(HAVE_UTMPX_H) || !defined(HAVE_LOGWTMP) rmut(); #ifdef HAVE_VHANGUP #ifndef __sgi vhangup(); /* XXX */ #endif #endif #else char *p; p = line + sizeof("/dev/") - 1; if (logout(p)) logwtmp(p, "", ""); chmod(line, 0666); chown(line, 0, 0); *p = 'p'; chmod(line, 0666); chown(line, 0, 0); #endif shutdown(net, 2); exit(1); }
/* * plogout - Logout the user. */ static void plogout(void) { #ifdef USE_PAM struct pam_conv pam_conversation; pam_handle_t *pamh; int pam_error; /* * Fill the pam_conversion structure. The PAM specification states that the * session must be able to be closed by a totally different handle from which * it was created. Hold the PAM group to their own specification! */ memset (&pam_conversation, '\0', sizeof (struct pam_conv)); pam_conversation.conv = &pam_conv; pam_error = pam_start ("ppp", user, &pam_conversation, &pamh); if (pam_error == PAM_SUCCESS) { pam_set_item (pamh, PAM_TTY, devnam); pam_close_session (pamh, PAM_SILENT); pam_end (pamh, PAM_SUCCESS); } #else char *tty; tty = devnam; if (strncmp(tty, _PATH_DEV, sizeof _PATH_DEV - 1) == 0) tty += 5; logwtmp(tty, "", ""); /* Wipe out wtmp logout entry */ logout(tty); /* Wipe out utmp */ #endif logged_in = FALSE; }
/* Records that the user has logged out. */ void record_logout(pid_t pid, const char *tty) { const char *line = tty + 5; /* /dev/ttyq8 -> ttyq8 */ if (logout(line)) logwtmp(line, "", ""); }
/* * Record login in wtmp file. */ void dologin(struct passwd *pw, struct sockaddr_in *sin) { char line[32]; char remotehost[32]; int wtmp, f; struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr, sizeof (struct in_addr), AF_INET); if (hp) { strncpy(remotehost, hp->h_name, sizeof (remotehost)); endhostent(); } else strncpy(remotehost, inet_ntoa(sin->sin_addr), sizeof (remotehost)); sprintf(line, "uucp%.4d", getpid()); logwtmp (line, pw->pw_name, remotehost); #if defined (PATH_LASTLOG) && defined (HAVE_STRUCT_LASTLOG) #define SCPYN(a, b) strncpy(a, b, sizeof (a)) if ((f = open(PATH_LASTLOG, O_RDWR)) >= 0) { struct lastlog ll; time(&ll.ll_time); lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); strcpy(line, remotehost); SCPYN(ll.ll_line, line); SCPYN(ll.ll_host, remotehost); (void) write(f, (char *) &ll, sizeof ll); (void) close(f); } #endif }
static void ip_up(void *opaque, int arg) { char *user = reduce(peer_authname); if (debug) notice("pptpd-logwtmp.so ip-up %s %s %s", ifname, user, pptpd_original_ip); logwtmp(ifname, user, pptpd_original_ip); }
/* * Close out the accounting files for a login session. * NB: should send a message to the session logger to avoid blocking. */ void clear_session_logs(session_t *sp) { char *line = sp->se_device + sizeof(_PATH_DEV) - 1; if (logout(line)) logwtmp(line, "", ""); }
/* * Run the system startup script. */ state_func_t runcom(void) { state_func_t next_transition; if ((next_transition = run_script(_PATH_RUNCOM)) != 0) return next_transition; runcom_mode = AUTOBOOT; /* the default */ /* NB: should send a message to the session logger to avoid blocking. */ logwtmp("~", "reboot", ""); return (state_func_t) read_ttys; }
static void ip_up(void *opaque, int arg) { char *user = peer_authname; if (pptpd_logwtmp_strip_domain) { char *sep = strstr(user, "//"); if (sep != NULL) user = sep + 2; } if (debug) notice("pptpd-logwtmp.so ip-up %s %s %s", ifname, user, pptpd_original_ip); logwtmp(ifname, user, pptpd_original_ip); }
long pty_logwtmp(const char *tty, const char *user, const char *host) { #ifndef HAVE_LOGWTMP PTY_STRUCT_UTMPX utx; int loggingin; size_t len; const char *cp; char utmp_id[5]; #endif #ifdef HAVE_LOGWTMP logwtmp(tty,user,host); return 0; #else loggingin = (user[0] != '\0'); memset(&utx, 0, sizeof(utx)); strncpy(utx.ut_line, tty, sizeof(utx.ut_line)); strncpy(utx.ut_user, user, sizeof(utx.ut_user)); #if (defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMPX_UT_HOST)) \ || (!defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMP_UT_HOST)) strncpy(utx.ut_host, host, sizeof(utx.ut_host)); utx.ut_host[sizeof(utx.ut_host) - 1] = '\0'; #endif #ifdef HAVE_SETUTXENT gettimeofday(&utx.ut_tv, NULL); #else (void)time(&utx.ut_time); #endif utx.ut_pid = (loggingin ? getpid() : 0); utx.ut_type = (loggingin ? USER_PROCESS : DEAD_PROCESS); len = strlen(tty); if (len >= 2) cp = tty + len - 2; else cp = tty; snprintf(utmp_id, sizeof(utmp_id), "kr%s", cp); strncpy(utx.ut_id, utmp_id, sizeof(utx.ut_id)); #ifdef HAVE_SETUTXENT return ptyint_update_wtmpx(&utx); #else return ptyint_update_wtmp(&utx); #endif #endif /* !HAVE_LOGWTMP */ }
/* Records that the user has logged out. */ void record_logout(pid_t pid, const char *tty) { #if defined(SUPPORT_UTMP) || defined(SUPPORT_UTMPX) const char *line = tty + 5; /* /dev/ttyq8 -> ttyq8 */ #endif #ifdef SUPPORT_UTMP if (logout(line)) logwtmp(line, "", ""); #endif #ifdef SUPPORT_UTMPX /* XXX: no exit info yet */ if (logoutx(line, 0, DEAD_PROCESS)) logwtmpx(line, "", "", 0, DEAD_PROCESS); #endif }
PAM_EXTERN int pam_sm_close_session (pam_handle_t *pamh, int flags, int argc, const char **argv) { const char *terminal_line; if (!(_pam_parse(pamh, flags, argc, argv) & LASTLOG_WTMP)) return PAM_SUCCESS; terminal_line = get_tty(pamh); /* Wipe out utmp logout entry */ logwtmp(terminal_line, "", ""); return PAM_SUCCESS; }
/* Update umtp & wtmp as necessary, and change tty & pty permissions back to what they should be. */ void cleanup_session (char *tty, int pty_fd) { char *line; # ifdef PATH_TTY_PFX if (strncmp (tty, PATH_TTY_PFX, sizeof PATH_TTY_PFX - 1) == 0) line = tty + sizeof PATH_TTY_PFX - 1; else # endif /* PATH_TTY_PFX */ line = tty; if (logout (line)) logwtmp (line, "", ""); chmod (tty, 0666); chown (tty, 0, 0); fchmod (pty_fd, 0666); fchown (pty_fd, 0, 0); }
void dologout (void) { int pid; #ifdef HAVE_WAITPID while ((pid = waitpid (-1, 0, WNOHANG)) > 0) #else # ifdef HAVE_WAIT3 while ((pid = wait3 (0, WNOHANG, 0)) > 0) # else while ((pid = wait (0)) > 0) # endif /* HAVE_WAIT3 */ #endif /* HAVE_WAITPID */ { char line[100]; sprintf (line, "uucp%.4d", pid); logwtmp (line, "", ""); } }
static int syslogin_perform_logout(struct logininfo *li) { # ifdef HAVE_LOGOUT char line[UT_LINESIZE]; (void)line_stripname(line, li->line, sizeof(line)); if (!logout(line)) logit("%s: logout() returned an error", __func__); # ifdef HAVE_LOGWTMP else logwtmp(line, "", ""); # endif /* FIXME: (ATL - if the need arises) What to do if we have * login, but no logout? what if logout but no logwtmp? All * routines are in libutil so they should all be there, * but... */ # endif return (1); }
long pty_logwtmp(const char *tty, const char *user, const char *host) { struct utmp ut; #ifdef HAVE_LOGWTMP logwtmp(tty,user,host); return 0; #else memset(&ut, 0, sizeof(ut)); #ifdef HAVE_STRUCT_UTMP_UT_HOST strncpy(ut.ut_host, host, sizeof(ut.ut_host)); ut.ut_host[sizeof(ut.ut_host) - 1] = '\0'; #endif strncpy(ut.ut_line, tty, sizeof(ut.ut_line)); strncpy(ut.ut_name, user, sizeof(ut.ut_name)); return ptyint_update_wtmp(&ut); #endif /* !HAVE_LOGWTMP */ }
RETSIGTYPE cleanup (int signo ARG_UNUSED) { char *p; p = line + sizeof (PATH_DEV) - 1; #ifdef UTMPX utmp_logout (p); chmod (line, 0644); chown (line, 0, 0); #else if (logout (p)) logwtmp (p, "", ""); chmod (line, 0666); chown (line, 0, 0); *p = 'p'; chmod (line, 0666); chown (line, 0, 0); #endif shutdown (netf, 2); exit (1); }
static int syslogin_perform_logout(struct logininfo *li) { # ifdef HAVE_LOGOUT char line[8]; (void)line_stripname(line, li->line, sizeof(line)); if (!logout(line)) { dropbear_log(LOG_WARNING, "syslogin_perform_logout: logout(%s) returned an error: %s", line, strerror(errno)); # ifdef HAVE_LOGWTMP } else { logwtmp(line, "", ""); # endif } /* FIXME: (ATL - if the need arises) What to do if we have * login, but no logout? what if logout but no logwtmp? All * routines are in libutil so they should all be there, * but... */ # endif return 1; }
/* * Record login in wtmp file. */ void dologin(struct passwd *pw, struct sockaddr *sin) { #if __FreeBSD_version >= 900007 struct utmpx ut; memset(&ut, 0, sizeof ut); ut.ut_type = USER_PROCESS; gettimeofday(&ut.ut_tv, NULL); ut.ut_pid = getpid(); snprintf(ut.ut_id, sizeof ut.ut_id, "%xuucp", ut.ut_pid); SCPYN(ut.ut_user, pw->pw_name); realhostname_sa(ut.ut_host, sizeof ut.ut_host, sin, sin->sa_len); pututxline(&ut); #else char line[32]; char remotehost[UT_HOSTSIZE + 1]; int f; time_t cur_time; realhostname_sa(remotehost, sizeof(remotehost) - 1, sin, sin->sa_len); remotehost[sizeof remotehost - 1] = '\0'; /* hack, but must be unique and no tty line */ sprintf(line, "uucp%ld", (long)getpid()); time(&cur_time); if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) { struct lastlog ll; ll.ll_time = cur_time; lseek(f, (off_t)pw->pw_uid * sizeof(struct lastlog), L_SET); SCPYN(ll.ll_line, line); SCPYN(ll.ll_host, remotehost); (void) write(f, (char *) &ll, sizeof ll); (void) close(f); } logwtmp(line, pw->pw_name, remotehost); #endif }
/* * cleanup() * * This is the routine to call when we are all through, to * clean up anything that needs to be cleaned up. */ void cleanup(int sig) { char *p; (void)sig; p = line + sizeof("/dev/") - 1; if (logout(p)) logwtmp(p, "", ""); #ifdef PARANOID_TTYS /* * dholland 16-Aug-96 chmod the tty when not in use * This will make it harder to attach unwanted stuff to it * (which is a security risk) but will break some programs. */ chmod(line, 0600); #else chmod(line, 0666); #endif chown(line, 0, 0); *p = 'p'; chmod(line, 0666); chown(line, 0, 0); shutdown(net, 2); exit(0); }
void dologout(void) { int status; pid_t pid; #if __FreeBSD_version >= 900007 struct utmpx ut; #else char line[32]; #endif while ((pid=wait((int *)&status)) > 0) { #if __FreeBSD_version >= 900007 memset(&ut, 0, sizeof ut); ut.ut_type = DEAD_PROCESS; gettimeofday(&ut.ut_tv, NULL); ut.ut_pid = pid; snprintf(ut.ut_id, sizeof ut.ut_id, "%xuucp", pid); pututxline(&ut); #else sprintf(line, "uucp%ld", (long)pid); logwtmp(line, "", ""); #endif } }
slave() { int length; int senddateack; long electiontime, refusetime, looktime; u_short seq; char candidate[MAXHOSTNAMELEN]; struct tsp *msg, to, *readmsg(); struct sockaddr_in saveaddr, msaveaddr; struct timeval wait; struct timeval time, otime; struct tsp *answer, *acksend(); int timeout(); char *date(); long casual(); int bytenetorder(); char olddate[32]; struct sockaddr_in server; register struct netinfo *ntp; int ind; struct tsp resp; extern int Mflag; extern int justquit; #ifdef MEASURE extern FILE *fp; #endif if (slavenet) { resp.tsp_type = TSP_SLAVEUP; resp.tsp_vers = TSPVERSION; (void)strcpy(resp.tsp_name, hostname); bytenetorder(&resp); if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, &slavenet->dest_addr, sizeof(struct sockaddr_in)) < 0) { syslog(LOG_ERR, "sendto: %m"); exit(1); } } if (status & MASTER) { #ifdef MEASURE if (fp == NULL) { fp = fopen("/usr/adm/timed.masterlog", "w"); setlinebuf(fp); } #endif syslog(LOG_INFO, "THIS MACHINE IS A SUBMASTER"); if (trace) { fprintf(fd, "THIS MACHINE IS A SUBMASTER\n"); } for (ntp = nettab; ntp != NULL; ntp = ntp->next) if (ntp->status == MASTER) masterup(ntp); } else { syslog(LOG_INFO, "THIS MACHINE IS A SLAVE"); if (trace) { fprintf(fd, "THIS MACHINE IS A SLAVE\n"); } } seq = 0; senddateack = OFF; refusetime = 0; (void)gettimeofday(&time, (struct timezone *)0); electiontime = time.tv_sec + delay2; if (Mflag) if (justquit) looktime = time.tv_sec + delay2; else looktime = 1; else looktime = 0; loop: length = sizeof(struct sockaddr_in); (void)gettimeofday(&time, (struct timezone *)0); if (time.tv_sec > electiontime) { if (trace) fprintf(fd, "election timer expired\n"); longjmp(jmpenv, 1); } if (looktime && time.tv_sec > looktime) { if (trace) fprintf(fd, "Looking for nets to master and loops\n"); if (nignorednets > 0) { for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == IGNORE) { lookformaster(ntp); if (ntp->status == MASTER) masterup(ntp); else ntp->status = IGNORE; } } setstatus(); #ifdef MEASURE /* * Check to see if we just became master * (file not open) */ if (fp == NULL) { fp = fopen("/usr/adm/timed.masterlog", "w"); setlinebuf(fp); } #endif } for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == MASTER) { to.tsp_type = TSP_LOOP; to.tsp_vers = TSPVERSION; to.tsp_seq = sequence++; to.tsp_hopcnt = 10; (void)strcpy(to.tsp_name, hostname); bytenetorder(&to); if (sendto(sock, (char *)&to, sizeof(struct tsp), 0, &ntp->dest_addr, sizeof(struct sockaddr_in)) < 0) { syslog(LOG_ERR, "sendto: %m"); exit(1); } } } (void)gettimeofday(&time, (struct timezone *)0); looktime = time.tv_sec + delay2; } wait.tv_sec = electiontime - time.tv_sec + 10; wait.tv_usec = 0; msg = readmsg(TSP_ANY, (char *)ANYADDR, &wait, (struct netinfo *)NULL); if (msg != NULL) { switch (msg->tsp_type) { case TSP_SETDATE: #ifdef TESTING case TSP_TEST: #endif case TSP_MSITE: case TSP_TRACEOFF: case TSP_TRACEON: break; case TSP_MASTERUP: if (fromnet == NULL) { if (trace) { fprintf(fd, "slave ignored: "); print(msg, &from); } goto loop; } break; default: if (fromnet == NULL || fromnet->status == IGNORE) { if (trace) { fprintf(fd, "slave ignored: "); print(msg, &from); } goto loop; } break; } switch (msg->tsp_type) { case TSP_ADJTIME: if (fromnet->status != SLAVE) break; (void)gettimeofday(&time, (struct timezone *)0); electiontime = time.tv_sec + delay2; if (seq != msg->tsp_seq) { seq = msg->tsp_seq; if ((status & SUBMASTER) == SUBMASTER) { synch((msg->tsp_time.tv_sec * 1000) + (msg->tsp_time.tv_usec / 1000)); } else { adjclock(&(msg->tsp_time)); } } break; case TSP_SETTIME: if (fromnet->status != SLAVE) break; if (seq == msg->tsp_seq) break; seq = msg->tsp_seq; (void)strcpy(olddate, date()); (void)gettimeofday(&otime, (struct timezone *)0); (void)settimeofday(&msg->tsp_time, (struct timezone *)0); syslog(LOG_NOTICE, "date changed by %s from: %s", msg->tsp_name, olddate); logwtmp(otime, msg->tsp_time); if ((status & SUBMASTER) == SUBMASTER) spreadtime(); (void)gettimeofday(&time, (struct timezone *)0); electiontime = time.tv_sec + delay2; if (senddateack == ON) { senddateack = OFF; msg->tsp_type = TSP_DATEACK; (void)strcpy(msg->tsp_name, hostname); bytenetorder(msg); length = sizeof(struct sockaddr_in); if (sendto(sock, (char *)msg, sizeof(struct tsp), 0, &saveaddr, length) < 0) { syslog(LOG_ERR, "sendto: %m"); exit(1); } } break; case TSP_MASTERUP: if (slavenet && fromnet != slavenet) break; makeslave(fromnet); setstatus(); msg->tsp_type = TSP_SLAVEUP; msg->tsp_vers = TSPVERSION; (void)strcpy(msg->tsp_name, hostname); bytenetorder(msg); answerdelay(); length = sizeof(struct sockaddr_in); if (sendto(sock, (char *)msg, sizeof(struct tsp), 0, &from, length) < 0) { syslog(LOG_ERR, "sendto: %m"); exit(1); } backoff = 1; delay2 = casual((long)MINTOUT, (long)MAXTOUT); (void)gettimeofday(&time, (struct timezone *)0); electiontime = time.tv_sec + delay2; refusetime = 0; break; case TSP_MASTERREQ: if (fromnet->status != SLAVE) break; (void)gettimeofday(&time, (struct timezone *)0); electiontime = time.tv_sec + delay2; break; case TSP_SETDATE: saveaddr = from; msg->tsp_type = TSP_SETDATEREQ; msg->tsp_vers = TSPVERSION; (void)strcpy(msg->tsp_name, hostname); for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == SLAVE) break; } if (ntp == NULL) break; answer = acksend(msg, &ntp->dest_addr, (char *)ANYADDR, TSP_DATEACK, ntp); if (answer != NULL) { msg->tsp_type = TSP_ACK; bytenetorder(msg); length = sizeof(struct sockaddr_in); if (sendto(sock, (char *)msg, sizeof(struct tsp), 0, &saveaddr, length) < 0) { syslog(LOG_ERR, "sendto: %m"); exit(1); } senddateack = ON; } break; case TSP_SETDATEREQ: saveaddr = from; if (status != SUBMASTER || fromnet->status != MASTER) break; for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == SLAVE) break; } ind = findhost(msg->tsp_name); if (ind < 0) { syslog(LOG_WARNING, "DATEREQ from uncontrolled machine"); break; } syslog(LOG_DEBUG, "forwarding date change request for %s", msg->tsp_name); (void)strcpy(msg->tsp_name, hostname); answer = acksend(msg, &ntp->dest_addr, (char *)ANYADDR, TSP_DATEACK, ntp); if (answer != NULL) { msg->tsp_type = TSP_DATEACK; bytenetorder(msg); length = sizeof(struct sockaddr_in); if (sendto(sock, (char *)msg, sizeof(struct tsp), 0, &saveaddr, length) < 0) { syslog(LOG_ERR, "sendto: %m"); exit(1); } } break; case TSP_TRACEON: if (!(trace)) { fd = fopen(tracefile, "w"); setlinebuf(fd); fprintf(fd, "Tracing started on: %s\n\n", date()); } trace = ON; break; case TSP_TRACEOFF: if (trace) { fprintf(fd, "Tracing ended on: %s\n", date()); (void)fclose(fd); } #ifdef GPROF moncontrol(0); _mcleanup(); moncontrol(1); #endif trace = OFF; break; case TSP_SLAVEUP: if ((status & MASTER) && fromnet->status == MASTER) { ind = addmach(msg->tsp_name, &from); newslave(ind, msg->tsp_seq); } break; case TSP_ELECTION: if (fromnet->status == SLAVE) { (void)gettimeofday(&time, (struct timezone *)0); electiontime = time.tv_sec + delay2; seq = 0; /* reset sequence number */ if (time.tv_sec < refusetime) msg->tsp_type = TSP_REFUSE; else { msg->tsp_type = TSP_ACCEPT; refusetime = time.tv_sec + 30; } (void)strcpy(candidate, msg->tsp_name); (void)strcpy(msg->tsp_name, hostname); answerdelay(); server = from; answer = acksend(msg, &server, candidate, TSP_ACK, (struct netinfo *)NULL); if (answer == NULL) syslog(LOG_WARNING, "no answer from master candidate\n"); } else { /* fromnet->status == MASTER */ to.tsp_type = TSP_QUIT; (void)strcpy(to.tsp_name, hostname); server = from; answer = acksend(&to, &server, msg->tsp_name, TSP_ACK, (struct netinfo *)NULL); if (answer == NULL) { syslog(LOG_WARNING, "election error: no reply to QUIT"); } else { (void) addmach(msg->tsp_name, &from); } } break; case TSP_CONFLICT: if (fromnet->status != MASTER) break; /* * After a network partition, there can be * more than one master: the first slave to * come up will notify here the situation. */ (void)strcpy(to.tsp_name, hostname); if (fromnet == NULL) break; for(;;) { to.tsp_type = TSP_RESOLVE; answer = acksend(&to, &fromnet->dest_addr, (char *)ANYADDR, TSP_MASTERACK, fromnet); if (answer == NULL) break; to.tsp_type = TSP_QUIT; server = from; msg = acksend(&to, &server, answer->tsp_name, TSP_ACK, (struct netinfo *)NULL); if (msg == NULL) { syslog(LOG_WARNING, "conflict error: no reply to QUIT"); } else { (void) addmach(answer->tsp_name, &from); } } masterup(fromnet); break; case TSP_MSITE: if (!slavenet) break; msaveaddr = from; msg->tsp_type = TSP_MSITEREQ; msg->tsp_vers = TSPVERSION; (void)strcpy(msg->tsp_name, hostname); answer = acksend(msg, &slavenet->dest_addr, (char *)ANYADDR, TSP_ACK, slavenet); if (answer != NULL) { msg->tsp_type = TSP_ACK; length = sizeof(struct sockaddr_in); bytenetorder(msg); if (sendto(sock, (char *)msg, sizeof(struct tsp), 0, &msaveaddr, length) < 0) { syslog(LOG_ERR, "sendto: %m"); exit(1); } } break; case TSP_ACCEPT: case TSP_REFUSE: break; case TSP_RESOLVE: break; case TSP_QUIT: /* become slave */ #ifdef MEASURE if (fp != NULL) { (void)fclose(fp); fp = NULL; } #endif longjmp(jmpenv, 2); break; #ifdef TESTING case TSP_TEST: electiontime = 0; break; #endif case TSP_MSITEREQ: if (status & MASTER) break; if (trace) { fprintf(fd, "garbage: "); print(msg, &from); } break; case TSP_LOOP: /* looking for loops of masters */ if ( !(status & MASTER)) break; if (fromnet->status == SLAVE) { if ( !strcmp(msg->tsp_name, hostname)) { for(;;) { to.tsp_type = TSP_RESOLVE; answer = acksend(&to, &fromnet->dest_addr, (char *)ANYADDR, TSP_MASTERACK, fromnet); if (answer == NULL) break; to.tsp_type = TSP_QUIT; (void)strcpy(to.tsp_name, hostname); server = from; answer = acksend(&to, &server, answer->tsp_name, TSP_ACK, (struct netinfo *)NULL); if (answer == NULL) { syslog(LOG_ERR, "loop kill error"); } else { electiontime = 0; } } } else { if (msg->tsp_hopcnt-- <= 0) break; bytenetorder(msg); ntp = nettab; for (; ntp != NULL; ntp = ntp->next) if (ntp->status == MASTER) if (sendto(sock, (char *)msg, sizeof(struct tsp), 0, &ntp->dest_addr, length) < 0) { syslog(LOG_ERR, "sendto: %m"); exit(1); } } } else { /* * We should not have received this from a net * we are master on. There must be two masters * in this case. */ if (fromnet->my_addr.s_addr == from.sin_addr.s_addr) break; for (;;) { to.tsp_type = TSP_RESOLVE; answer = acksend(&to, &fromnet->dest_addr, (char *)ANYADDR, TSP_MASTERACK, fromnet); if (answer == NULL) break; to.tsp_type = TSP_QUIT; (void)strcpy(to.tsp_name, hostname); server = from; answer = acksend(&to, &server, answer->tsp_name, TSP_ACK, (struct netinfo *)NULL); if (answer == NULL) { syslog(LOG_ERR, "loop kill error2"); } else { (void)addmach(msg->tsp_name, &from); } } } break; default: if (trace) { fprintf(fd, "garbage: "); print(msg, &from); } break; } } goto loop; }
static void ip_down(void *opaque, int arg) { if (debug) notice("pptpd-logwtmp.so ip-down %s", ifname); logwtmp(ifname, "", ""); }
void setthetime(char *p) { struct tm *lt; struct timeval tv; char *dot, *t; int yearset = 0; for (t = p, dot = NULL; *t; ++t) { if (isdigit((unsigned char)*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } lt = localtime(&tval); lt->tm_isdst = -1; /* correct for DST */ if (dot != NULL) { /* .SS */ *dot++ = '\0'; if (strlen(dot) != 2) badformat(); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badformat(); } else lt->tm_sec = 0; switch (strlen(p)) { case 12: /* cc */ lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; yearset = 1; /* FALLTHROUGH */ case 10: /* yy */ if (!yearset) { /* mask out current year, leaving only century */ lt->tm_year = ((lt->tm_year / 100) * 100); } lt->tm_year += ATOI2(p); /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if ((lt->tm_mon > 12) || !lt->tm_mon) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); if ((lt->tm_mday > 31) || !lt->tm_mday) badformat(); /* FALLTHROUGH */ case 4: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badformat(); break; default: badformat(); } /* convert broken-down time to UTC clock time */ if ((tval = mktime(lt)) < 0) errx(1, "specified date is outside allowed range"); if (jflag) return; /* set the time */ if (slidetime) { struct timeval tv_current; if (gettimeofday(&tv_current, NULL) == -1) err(1, "Could not get local time of day"); tv.tv_sec = tval - tv_current.tv_sec; tv.tv_usec = 0; if (adjtime(&tv, NULL) == -1) errx(1, "adjtime"); } else { #ifndef SMALL logwtmp("|", "date", ""); #endif tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, NULL)) err(1, "settimeofday"); #ifndef SMALL logwtmp("{", "date", ""); #endif } if ((p = getlogin()) == NULL) p = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); }
void exec_shell(struct conf *cfp, int fd, int parentfd) { int master, slave; pid_t pid; char line[MAXPATHLEN]; char *tty; #ifdef HAVE_UTMP_H struct utmp ut; #elif HAVE_UTMPX_H struct utmpx ut; struct timeval tv; #endif #if defined(HAVE_UTMP_H) || defined(HAVE_UTMPX_H) memset(&ut, 0, sizeof(ut)); #endif if (pipe(pipechld) < 0) { syslog(LOG_ERR, "exec_shell() pipe %m"); _exit(1); } (void)non_blocking(pipechld[0]); (void)non_blocking(pipechld[1]); if (openpty(&master, &slave, line, NULL, NULL) == -1) { syslog(LOG_ERR, "openpty %m"); _exit(1) ; } /* * pts/x compatible */ if ((tty = strstr(line, "/dev/"))) tty += 5; else tty = line; #if defined(HAVE_UTMP_H) || defined(HAVE_UTMPX_H) if (cfp->utmp) { if (cfp->utname) { #ifdef HAVE_UTMP_H (void)strncpy(ut.ut_name, cfp->utname, sizeof(ut.ut_name)-1); ut.ut_name[sizeof(ut.ut_name)-1] = '\0'; #elif HAVE_UTMPX_H (void)strncpy(ut.ut_user, cfp->utname, sizeof(ut.ut_user)-1); ut.ut_user[sizeof(ut.ut_user)-1] = '\0'; #endif } else { struct passwd *pw; pw = get_pwentry(cfp->havesetuser ? cfp->setuser : \ 0); #ifdef HAVE_UTMP_H (void)strncpy(ut.ut_name, pw->pw_name, sizeof(ut.ut_name)-1); ut.ut_name[sizeof(ut.ut_name)-1] = '\0'; #elif HAVE_UTMPX_H (void)strncpy(ut.ut_user, pw->pw_name, sizeof(ut.ut_user)-1); ut.ut_user[sizeof(ut.ut_user)-1] = '\0'; #endif } (void)strncpy(ut.ut_line, tty, sizeof(ut.ut_line)-1); ut.ut_line[sizeof(ut.ut_line)-1] = '\0'; if (cfp->uthost) { (void)strncpy(ut.ut_host, cfp->uthost, sizeof(ut.ut_host)-1); ut.ut_host[sizeof(ut.ut_host)-1] = '\0'; } #ifdef HAVE_UTMP_H (void)time(&ut.ut_time); #elif HAVE_UTMPX_H (void)gettimeofday(&tv, NULL); ut.ut_tv.tv_sec = tv.tv_sec; ut.ut_tv.tv_usec = tv.tv_usec; (void)strncpy(ut.ut_id, ut.ut_line, sizeof(ut.ut_id)-1); ut.ut_line[sizeof(ut.ut_line)-1] = '\0'; ut.ut_pid = getpid(); ut.ut_type = USER_PROCESS; #endif } #endif /* * overwriting signal disposition */ (void)signal(SIGCHLD, sig_chld); switch (pid = fork()) { case -1: syslog(LOG_ERR, "forkpty: %m"); _exit(1); case 0: (void)close(parentfd); (void)close(pipechld[0]); (void)close(pipechld[1]); (void)close(master); (void)close(fd); (void)login_tty(slave); #ifdef HAVE_UTMP_H login(&ut); #elif HAVE_UTMPX_H setutxent(); (void)pututxline(&ut); #endif set_privileges(cfp); /* * SUIP PROGRAM HERE */ #ifdef __NetBSD__ (void)execl(_PATH_BSHELL,"sh", "-c",cfp->suipfile,(char *)NULL); #else (void)execl(_PATH_BSHELL, "sh", "-p", "-c", cfp->suipfile, (char *)NULL); #endif _exit(127); default: { int ctrls; int exit_status = 0; (void)close(slave); /* * trying to open a control channel * control_create() returns the number of bytes which were * written * select_fd() returns -1 if errors exist you can check errno */ if (control_create(&ctrls, fd) == 1) { if (select_fd(cfp, fd, master, ctrls, parentfd) < 0) exit_status = 1; } else { syslog(LOG_ERR, "can't open ctrl chan"); exit_status = 1; } #if defined(HAVE_UTMP_H) || defined(HAVE_UTMPX_H) if (cfp->utmp) { #ifdef HAVE_UTMP_H if (!logout(tty)) { syslog(LOG_ERR, "unable to logout on %s", tty); exit_status = 1; } else logwtmp(tty, "", ""); #elif HAVE_UTMPX_H ut.ut_type = DEAD_PROCESS; (void)gettimeofday(&tv, NULL); ut.ut_tv.tv_sec = tv.tv_sec; ut.ut_tv.tv_usec = tv.tv_usec; (void)memset(&ut.ut_user, 0, sizeof(ut.ut_user)); setutxent(); if (pututxline(&ut) == NULL) { syslog(LOG_ERR, "unable to logout on %s (utmpx)", tty); exit_status = 1; } endutxent(); #endif } #endif cleanup(line); _exit(exit_status); }} /* * never reached */ _exit(1); }
int main(int argc, char *argv[]) { struct passwd *pw; int ch, howto, i, fd, kflag, lflag, nflag, qflag, pflag, sverrno; u_int pageins; char *kernel = NULL, *p; const char *user; if (strstr((p = strrchr(*argv, '/')) ? p + 1 : *argv, "halt")) { dohalt = 1; howto = RB_HALT; } else howto = 0; kflag = lflag = nflag = qflag = 0; while ((ch = getopt(argc, argv, "dk:lnpq")) != -1) switch(ch) { case 'd': howto |= RB_DUMP; break; case 'k': kflag = 1; kernel = optarg; break; case 'l': lflag = 1; break; case 'n': nflag = 1; howto |= RB_NOSYNC; break; case 'p': pflag = 1; howto |= (RB_POWEROFF | RB_HALT); break; case 'q': qflag = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; if ((howto & (RB_DUMP | RB_HALT)) == (RB_DUMP | RB_HALT)) errx(1, "cannot dump (-d) when halting; must reboot instead"); if (geteuid()) { errno = EPERM; err(1, NULL); } if (qflag) { reboot(howto); err(1, NULL); } if (kflag) { fd = open("/boot/nextboot.conf", O_WRONLY | O_CREAT | O_TRUNC, 0444); if (fd != -1) { write(fd, "kernel=\"", 8L); write(fd, kernel, strlen(kernel)); write(fd, "\"\n", 2); close(fd); } } /* Log the reboot. */ if (!lflag) { if ((user = getlogin()) == NULL) user = (pw = getpwuid(getuid())) ? pw->pw_name : "???"; if (dohalt) { openlog("halt", 0, LOG_AUTH | LOG_CONS); syslog(LOG_CRIT, "halted by %s", user); } else { openlog("reboot", 0, LOG_AUTH | LOG_CONS); syslog(LOG_CRIT, "rebooted by %s", user); } } logwtmp("~", "shutdown", ""); /* * Do a sync early on, so disks start transfers while we're off * killing processes. Don't worry about writes done before the * processes die, the reboot system call syncs the disks. */ if (!nflag) sync(); /* Just stop init -- if we fail, we'll restart it. */ if (kill(1, SIGTSTP) == -1) err(1, "SIGTSTP init"); /* Ignore the SIGHUP we get when our parent shell dies. */ signal(SIGHUP, SIG_IGN); /* Send a SIGTERM first, a chance to save the buffers. */ if (kill(-1, SIGTERM) == -1) err(1, "SIGTERM processes"); /* * After the processes receive the signal, start the rest of the * buffers on their way. Wait 5 seconds between the SIGTERM and * the SIGKILL to give everybody a chance. If there is a lot of * paging activity then wait longer, up to a maximum of approx * 60 seconds. */ sleep(2); for (i = 0; i < 20; i++) { pageins = get_pageins(); if (!nflag) sync(); sleep(3); if (get_pageins() == pageins) break; } for (i = 1;; ++i) { if (kill(-1, SIGKILL) == -1) { if (errno == ESRCH) break; goto restart; } if (i > 5) { fprintf(stderr, "WARNING: some process(es) wouldn't die\n"); break; } sleep(2 * i); } reboot(howto); /* FALLTHROUGH */ restart: sverrno = errno; errx(1, "%s%s", kill(1, SIGHUP) == -1 ? "(can't restart init): " : "", strerror(sverrno)); /* NOTREACHED */ }
static void setthetime(const char *fmt, const char *p, int jflag, int nflag) { struct tm *lt; struct timeval tv; const char *dot, *t; int century; if (fmt != NULL) { lt = localtime(&tval); t = strptime(p, fmt, lt); if (t == NULL) { fprintf(stderr, "Failed conversion of ``%s''" " using format ``%s''\n", p, fmt); badformat(); } else if (*t != '\0') fprintf(stderr, "Warning: Ignoring %ld extraneous" " characters in date string (%s)\n", (long) strlen(t), t); } else { for (t = p, dot = NULL; *t; ++t) { if (isdigit(*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } lt = localtime(&tval); if (dot != NULL) { /* .ss */ dot++; /* *dot++ = '\0'; */ if (strlen(dot) != 2) badformat(); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badformat(); } else lt->tm_sec = 0; century = 0; /* if p has a ".ss" field then let's pretend it's not there */ switch (strlen(p) - ((dot != NULL) ? 3 : 0)) { case 12: /* cc */ lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; century = 1; /* FALLTHROUGH */ case 10: /* yy */ if (century) lt->tm_year += ATOI2(p); else { /* hack for 2000 ;-} */ lt->tm_year = ATOI2(p); if (lt->tm_year < 69) lt->tm_year += 2000 - TM_YEAR_BASE; else lt->tm_year += 1900 - TM_YEAR_BASE; } /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if (lt->tm_mon > 12) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); if (lt->tm_mday > 31) badformat(); /* FALLTHROUGH */ case 4: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badformat(); break; default: badformat(); } } /* Let mktime() decide whether summer time is in effect. */ lt->tm_isdst = -1; /* convert broken-down time to GMT clock time */ if ((tval = mktime(lt)) == -1) errx(1, "nonexistent time"); if (!jflag) { /* set the time */ if (nflag || netsettime(tval)) { logwtmp("|", "date", ""); tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, NULL)) err(1, "settimeofday (timeval)"); logwtmp("{", "date", ""); } if ((p = getlogin()) == NULL) p = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); } }
static int plogin(char *user, char *passwd, char **msg, int *msglen) { #ifdef USE_PAM struct pam_conv pam_conversation; pam_handle_t *pamh; int pam_error; /* * Fill the pam_conversion structure */ memset (&pam_conversation, '\0', sizeof (struct pam_conv)); pam_conversation.conv = &pam_conv; pam_error = pam_start ("ppp", user, &pam_conversation, &pamh); if (pam_error != PAM_SUCCESS) { *msg = MY_PAM_STRERROR (pam_error); return UPAP_AUTHNAK; } /* * Define the fields for the credintial validation */ pam_set_item (pamh, PAM_TTY, devnam); PAM_username = user; PAM_password = passwd; /* * Validate the user */ pam_error = pam_authenticate (pamh, PAM_SILENT); if (pam_error == PAM_SUCCESS) { pam_error = pam_acct_mgmt (pamh, PAM_SILENT); /* start a session for this user. Session closed when link ends. */ if (pam_error == PAM_SUCCESS) pam_open_session (pamh, PAM_SILENT); } *msg = MY_PAM_STRERROR (pam_error); PAM_username = PAM_password = ""; /* * Clean up the mess */ pam_end (pamh, pam_error); if (pam_error != PAM_SUCCESS) return UPAP_AUTHNAK; /* * Use the non-PAM methods directly */ #else /* #ifdef USE_PAM */ struct passwd *pw; struct utmp utmp; struct timeval tp; char *tty; #ifdef HAS_SHADOW struct spwd *spwd; struct spwd *getspnam(); #endif pw = getpwnam(user); endpwent(); if (pw == NULL) { return (UPAP_AUTHNAK); } /* * Check that the user is not listed in /etc/ppp/ppp.deny * and that the user's shell is listed in /etc/ppp/ppp.shells * if /etc/ppp/ppp.shells exists. */ if (checkfile(_PATH_PPPDENY, user) == 1) { syslog(LOG_WARNING, "upap user %s: login denied in %s", user, _PATH_PPPDENY); return (UPAP_AUTHNAK); } if (checkfile(_PATH_PPPSHELLS, pw->pw_shell) == 0) { syslog(LOG_WARNING, "upap user %s: shell %s not in %s", user, pw->pw_shell, _PATH_PPPSHELLS); return (UPAP_AUTHNAK); } #ifdef HAS_SHADOW spwd = getspnam(user); endspent(); if (spwd) { /* check the age of the password entry */ long now = time(NULL) / 86400L; if ((spwd->sp_expire > 0 && now >= spwd->sp_expire) || ((spwd->sp_max >= 0 && spwd->sp_max < 10000) && spwd->sp_lstchg >= 0 && now >= spwd->sp_lstchg + spwd->sp_max)) { syslog(LOG_WARNING, "Password for %s has expired", user); return (UPAP_AUTHNAK); } pw->pw_passwd = spwd->sp_pwdp; } #endif /* * If no passwd, don't let them login. */ if (pw->pw_passwd == NULL || *pw->pw_passwd == '\0' || strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd) != 0) return (UPAP_AUTHNAK); if (pw->pw_expire) { gettimeofday(&tp, NULL); if (tp.tv_sec >= pw->pw_expire) { syslog(LOG_INFO, "pap user %s account expired", user); return (UPAP_AUTHNAK); } } /* These functions are not enabled for PAM. The reason for this is that */ /* there is not necessarily a "passwd" entry for this user. That is */ /* real purpose of 'PAM' -- to virtualize the account data from the */ /* application. If you want to do the same thing, write the entry in */ /* the 'session' hook. */ /* Log in wtmp and utmp using login() */ tty = devnam; if (strncmp(tty, _PATH_DEV, sizeof _PATH_DEV - 1) == 0) tty += 5; if (logout(tty)) /* Already entered (by login?) */ logwtmp(tty, "", ""); #if defined(_PATH_LASTLOG) { struct lastlog ll; int fd; if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET); memset((void *)&ll, 0, sizeof(ll)); time(&ll.ll_time); strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); write(fd, (char *)&ll, sizeof(ll)); close(fd); } } #endif memset((void *)&utmp, 0, sizeof(utmp)); time(&utmp.ut_time); strncpy(utmp.ut_name, user, sizeof(utmp.ut_name)); strncpy(utmp.ut_host, ":PPP", sizeof(utmp.ut_host)); strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); login(&utmp); /* This logs us in wtmp too */ #endif /* #ifdef USE_PAM */ syslog(LOG_INFO, "user %s logged in", user); logged_in = TRUE; return (UPAP_AUTHACK); }