version 1.23, 2000/07/11 08:11:33 |
version 1.24, 2000/08/17 20:05:10 |
|
|
void session_proctitle(Session *s); |
void session_proctitle(Session *s); |
void do_exec_pty(Session *s, const char *command, struct passwd * pw); |
void do_exec_pty(Session *s, const char *command, struct passwd * pw); |
void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); |
void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); |
|
void do_login(Session *s); |
|
|
void |
void |
do_child(const char *command, struct passwd * pw, const char *term, |
do_child(const char *command, struct passwd * pw, const char *term, |
|
|
void |
void |
do_exec_pty(Session *s, const char *command, struct passwd * pw) |
do_exec_pty(Session *s, const char *command, struct passwd * pw) |
{ |
{ |
FILE *f; |
|
char buf[100], *time_string; |
|
char line[256]; |
|
const char *hostname; |
|
int fdout, ptyfd, ttyfd, ptymaster; |
int fdout, ptyfd, ttyfd, ptymaster; |
int quiet_login; |
|
pid_t pid; |
pid_t pid; |
socklen_t fromlen; |
|
struct sockaddr_storage from; |
|
struct stat st; |
|
time_t last_login_time; |
|
|
|
if (s == NULL) |
if (s == NULL) |
fatal("do_exec_pty: no session"); |
fatal("do_exec_pty: no session"); |
ptyfd = s->ptyfd; |
ptyfd = s->ptyfd; |
ttyfd = s->ttyfd; |
ttyfd = s->ttyfd; |
|
|
/* Get remote host name. */ |
|
hostname = get_canonical_hostname(); |
|
|
|
/* |
|
* Get the time when the user last logged in. Buf will be set to |
|
* contain the hostname the last login was from. |
|
*/ |
|
if (!options.use_login) { |
|
last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, |
|
buf, sizeof(buf)); |
|
} |
|
|
|
/* Fork the child. */ |
/* Fork the child. */ |
if ((pid = fork()) == 0) { |
if ((pid = fork()) == 0) { |
pid = getpid(); |
/* Child. Reinitialize the log because the pid has changed. */ |
|
|
/* Child. Reinitialize the log because the pid has |
|
changed. */ |
|
log_init(__progname, options.log_level, options.log_facility, log_stderr); |
log_init(__progname, options.log_level, options.log_facility, log_stderr); |
|
|
/* Close the master side of the pseudo tty. */ |
/* Close the master side of the pseudo tty. */ |
|
|
/* Close the extra descriptor for the pseudo tty. */ |
/* Close the extra descriptor for the pseudo tty. */ |
close(ttyfd); |
close(ttyfd); |
|
|
/* XXXX ? move to do_child() ??*/ |
/* record login, etc. similar to login(1) */ |
/* |
if (command == NULL && !options.use_login) |
* Get IP address of client. This is needed because we want |
do_login(s); |
* to record where the user logged in from. If the |
|
* connection is not a socket, let the ip address be 0.0.0.0. |
|
*/ |
|
memset(&from, 0, sizeof(from)); |
|
if (packet_connection_is_on_socket()) { |
|
fromlen = sizeof(from); |
|
if (getpeername(packet_get_connection_in(), |
|
(struct sockaddr *) & from, &fromlen) < 0) { |
|
debug("getpeername: %.100s", strerror(errno)); |
|
fatal_cleanup(); |
|
} |
|
} |
|
/* Record that there was a login on that terminal. */ |
|
record_login(pid, s->tty, pw->pw_name, pw->pw_uid, hostname, |
|
(struct sockaddr *)&from); |
|
|
|
/* Check if .hushlogin exists. */ |
|
snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir); |
|
quiet_login = stat(line, &st) >= 0; |
|
|
|
/* |
|
* If the user has logged in before, display the time of last |
|
* login. However, don't display anything extra if a command |
|
* has been specified (so that ssh can be used to execute |
|
* commands on a remote machine without users knowing they |
|
* are going to another machine). Login(1) will do this for |
|
* us as well, so check if login(1) is used |
|
*/ |
|
if (command == NULL && last_login_time != 0 && !quiet_login && |
|
!options.use_login) { |
|
/* Convert the date to a string. */ |
|
time_string = ctime(&last_login_time); |
|
/* Remove the trailing newline. */ |
|
if (strchr(time_string, '\n')) |
|
*strchr(time_string, '\n') = 0; |
|
/* Display the last login time. Host if displayed |
|
if known. */ |
|
if (strcmp(buf, "") == 0) |
|
printf("Last login: %s\r\n", time_string); |
|
else |
|
printf("Last login: %s from %s\r\n", time_string, buf); |
|
} |
|
/* |
|
* Print /etc/motd unless a command was specified or printing |
|
* it was disabled in server options or login(1) will be |
|
* used. Note that some machines appear to print it in |
|
* /etc/profile or similar. |
|
*/ |
|
if (command == NULL && options.print_motd && !quiet_login && |
|
!options.use_login) { |
|
/* Print /etc/motd if it exists. */ |
|
f = fopen("/etc/motd", "r"); |
|
if (f) { |
|
while (fgets(line, sizeof(line), f)) |
|
fputs(line, stdout); |
|
fclose(f); |
|
} |
|
} |
|
/* Do common processing for the child, such as execing the command. */ |
/* Do common processing for the child, such as execing the command. */ |
do_child(command, pw, s->term, s->display, s->auth_proto, |
do_child(command, pw, s->term, s->display, s->auth_proto, |
s->auth_data, s->tty); |
s->auth_data, s->tty); |
|
|
server_loop(pid, ptyfd, fdout, -1); |
server_loop(pid, ptyfd, fdout, -1); |
/* server_loop _has_ closed ptyfd and fdout. */ |
/* server_loop _has_ closed ptyfd and fdout. */ |
session_pty_cleanup(s); |
session_pty_cleanup(s); |
|
} |
|
} |
|
|
|
/* administrative, login(1)-like work */ |
|
void |
|
do_login(Session *s) |
|
{ |
|
FILE *f; |
|
char *time_string; |
|
char buf[256]; |
|
socklen_t fromlen; |
|
struct sockaddr_storage from; |
|
struct stat st; |
|
time_t last_login_time; |
|
struct passwd * pw = s->pw; |
|
pid_t pid = getpid(); |
|
|
|
/* |
|
* Get IP address of client. If the connection is not a socket, let |
|
* the address be 0.0.0.0. |
|
*/ |
|
memset(&from, 0, sizeof(from)); |
|
if (packet_connection_is_on_socket()) { |
|
fromlen = sizeof(from); |
|
if (getpeername(packet_get_connection_in(), |
|
(struct sockaddr *) & from, &fromlen) < 0) { |
|
debug("getpeername: %.100s", strerror(errno)); |
|
fatal_cleanup(); |
|
} |
|
} |
|
/* Record that there was a login on that tty from the remote host. */ |
|
record_login(pid, s->tty, pw->pw_name, pw->pw_uid, |
|
get_canonical_hostname(), |
|
(struct sockaddr *)&from); |
|
|
|
/* Done if .hushlogin exists. */ |
|
snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); |
|
if (stat(buf, &st) >= 0) |
|
return; |
|
/* |
|
* Get the time when the user last logged in. 'buf' will be set |
|
* to contain the hostname the last login was from. |
|
*/ |
|
last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, |
|
buf, sizeof(buf)); |
|
if (last_login_time != 0) { |
|
time_string = ctime(&last_login_time); |
|
if (strchr(time_string, '\n')) |
|
*strchr(time_string, '\n') = 0; |
|
if (strcmp(buf, "") == 0) |
|
printf("Last login: %s\r\n", time_string); |
|
else |
|
printf("Last login: %s from %s\r\n", time_string, buf); |
|
} |
|
if (options.print_motd) { |
|
f = fopen("/etc/motd", "r"); |
|
if (f) { |
|
while (fgets(buf, sizeof(buf), f)) |
|
fputs(buf, stdout); |
|
fclose(f); |
|
} |
} |
} |
} |
} |
|
|