- (bal) OpenBSD CVS Sync
- markus@cvs.openbsd.org 2002/02/15 23:11:26 [session.c] split do_child(), ok mouring@ Compiles under Redhat 7.2.. I cannot give any promises.. but I spent a good hour and half ensure all the right bits are in the right spots.. and it does seem to help out quite a bit for readiblity.
This commit is contained in:
parent
a9c039cf04
commit
4e97e85c03
|
@ -48,6 +48,11 @@
|
||||||
- (bal) Migrated AIX getuserattr and usrinfo code to
|
- (bal) Migrated AIX getuserattr and usrinfo code to
|
||||||
openbsd-compat/port-aix.[c] to improve readilbity of do_child() and
|
openbsd-compat/port-aix.[c] to improve readilbity of do_child() and
|
||||||
simplify our diffs against upstream source.
|
simplify our diffs against upstream source.
|
||||||
|
- (bal) OpenBSD CVS Sync
|
||||||
|
- markus@cvs.openbsd.org 2002/02/15 23:11:26
|
||||||
|
[session.c]
|
||||||
|
split do_child(), ok mouring@
|
||||||
|
|
||||||
|
|
||||||
20020218
|
20020218
|
||||||
- (tim) newer config.guess from ftp://ftp.gnu.org/gnu/config/config.guess
|
- (tim) newer config.guess from ftp://ftp.gnu.org/gnu/config/config.guess
|
||||||
|
@ -7645,4 +7650,4 @@
|
||||||
- Wrote replacements for strlcpy and mkdtemp
|
- Wrote replacements for strlcpy and mkdtemp
|
||||||
- Released 1.0pre1
|
- Released 1.0pre1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.1867 2002/02/19 20:27:55 mouring Exp $
|
$Id: ChangeLog,v 1.1868 2002/02/19 21:50:43 mouring Exp $
|
||||||
|
|
465
session.c
465
session.c
|
@ -33,7 +33,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: session.c,v 1.126 2002/02/14 23:28:00 markus Exp $");
|
RCSID("$OpenBSD: session.c,v 1.127 2002/02/15 23:11:26 markus Exp $");
|
||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "ssh1.h"
|
#include "ssh1.h"
|
||||||
|
@ -657,6 +657,7 @@ do_exec(Session *s, const char *command)
|
||||||
original_command = NULL;
|
original_command = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* administrative, login(1)-like work */
|
/* administrative, login(1)-like work */
|
||||||
void
|
void
|
||||||
do_login(Session *s, const char *command)
|
do_login(Session *s, const char *command)
|
||||||
|
@ -677,7 +678,7 @@ do_login(Session *s, const char *command)
|
||||||
if (packet_connection_is_on_socket()) {
|
if (packet_connection_is_on_socket()) {
|
||||||
fromlen = sizeof(from);
|
fromlen = sizeof(from);
|
||||||
if (getpeername(packet_get_connection_in(),
|
if (getpeername(packet_get_connection_in(),
|
||||||
(struct sockaddr *) & from, &fromlen) < 0) {
|
(struct sockaddr *) & from, &fromlen) < 0) {
|
||||||
debug("getpeername: %.100s", strerror(errno));
|
debug("getpeername: %.100s", strerror(errno));
|
||||||
fatal_cleanup();
|
fatal_cleanup();
|
||||||
}
|
}
|
||||||
|
@ -883,134 +884,13 @@ void copy_environment(char **source, char ***env, u_int *envsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static char **
|
||||||
* Performs common processing for the child, such as setting up the
|
do_setup_env(Session *s, const char *shell)
|
||||||
* environment, closing extra file descriptors, setting the user and group
|
|
||||||
* ids, and executing the command or shell.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
do_child(Session *s, const char *command)
|
|
||||||
{
|
{
|
||||||
const char *shell, *hostname = NULL, *cp = NULL;
|
|
||||||
struct passwd *pw = s->pw;
|
|
||||||
char buf[256];
|
char buf[256];
|
||||||
char cmd[1024];
|
u_int i, envsize;
|
||||||
FILE *f = NULL;
|
|
||||||
u_int envsize, i;
|
|
||||||
char **env;
|
char **env;
|
||||||
extern char **environ;
|
struct passwd *pw = s->pw;
|
||||||
struct stat st;
|
|
||||||
char *argv[10];
|
|
||||||
int do_xauth;
|
|
||||||
|
|
||||||
do_xauth =
|
|
||||||
s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
|
|
||||||
|
|
||||||
/* remove hostkey from the child's memory */
|
|
||||||
destroy_sensitive_data();
|
|
||||||
|
|
||||||
/* login(1) is only called if we execute the login shell */
|
|
||||||
if (options.use_login && command != NULL)
|
|
||||||
options.use_login = 0;
|
|
||||||
|
|
||||||
#if !defined(HAVE_OSF_SIA)
|
|
||||||
if (!options.use_login) {
|
|
||||||
# ifdef HAVE_LOGIN_CAP
|
|
||||||
if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
|
|
||||||
f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
|
|
||||||
_PATH_NOLOGIN), "r");
|
|
||||||
# else /* HAVE_LOGIN_CAP */
|
|
||||||
if (pw->pw_uid)
|
|
||||||
f = fopen(_PATH_NOLOGIN, "r");
|
|
||||||
# endif /* HAVE_LOGIN_CAP */
|
|
||||||
if (f) {
|
|
||||||
/* /etc/nologin exists. Print its contents and exit. */
|
|
||||||
while (fgets(buf, sizeof(buf), f))
|
|
||||||
fputs(buf, stderr);
|
|
||||||
fclose(f);
|
|
||||||
exit(254);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* HAVE_OSF_SIA */
|
|
||||||
|
|
||||||
/* Set login name, uid, gid, and groups. */
|
|
||||||
/* Login(1) does this as well, and it needs uid 0 for the "-h"
|
|
||||||
switch, so we let login(1) to this for us. */
|
|
||||||
if (!options.use_login) {
|
|
||||||
#ifdef HAVE_OSF_SIA
|
|
||||||
session_setup_sia(pw->pw_name, s->ttyfd == -1 ? NULL : s->tty);
|
|
||||||
if (!check_quietlogin(s, command))
|
|
||||||
do_motd();
|
|
||||||
#else /* HAVE_OSF_SIA */
|
|
||||||
#ifdef HAVE_CYGWIN
|
|
||||||
if (is_winnt) {
|
|
||||||
#else
|
|
||||||
if (getuid() == 0 || geteuid() == 0) {
|
|
||||||
#endif
|
|
||||||
# ifdef HAVE_GETUSERATTR
|
|
||||||
set_limits_from_userattr(pw->pw_name);
|
|
||||||
# endif /* HAVE_GETUSERATTR */
|
|
||||||
# ifdef HAVE_LOGIN_CAP
|
|
||||||
if (setusercontext(lc, pw, pw->pw_uid,
|
|
||||||
(LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
|
|
||||||
perror("unable to set user context");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
# else /* HAVE_LOGIN_CAP */
|
|
||||||
#if defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
|
|
||||||
/* Sets login uid for accounting */
|
|
||||||
if (getluid() == -1 && setluid(pw->pw_uid) == -1)
|
|
||||||
error("setluid: %s", strerror(errno));
|
|
||||||
#endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */
|
|
||||||
|
|
||||||
if (setlogin(pw->pw_name) < 0)
|
|
||||||
error("setlogin failed: %s", strerror(errno));
|
|
||||||
if (setgid(pw->pw_gid) < 0) {
|
|
||||||
perror("setgid");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
/* Initialize the group list. */
|
|
||||||
if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
|
|
||||||
perror("initgroups");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
endgrent();
|
|
||||||
# ifdef USE_PAM
|
|
||||||
/*
|
|
||||||
* PAM credentials may take the form of
|
|
||||||
* supplementary groups. These will have been
|
|
||||||
* wiped by the above initgroups() call.
|
|
||||||
* Reestablish them here.
|
|
||||||
*/
|
|
||||||
do_pam_setcred(0);
|
|
||||||
# endif /* USE_PAM */
|
|
||||||
# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
|
|
||||||
irix_setusercontext(pw);
|
|
||||||
# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
|
|
||||||
#ifdef _AIX
|
|
||||||
aix_usrinfo(s)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Permanently switch to the desired uid. */
|
|
||||||
permanently_set_uid(pw);
|
|
||||||
# endif /* HAVE_LOGIN_CAP */
|
|
||||||
}
|
|
||||||
#endif /* HAVE_OSF_SIA */
|
|
||||||
|
|
||||||
#ifdef HAVE_CYGWIN
|
|
||||||
if (is_winnt)
|
|
||||||
#endif
|
|
||||||
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
|
|
||||||
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Get the shell from the password data. An empty shell field is
|
|
||||||
* legal, and means /bin/sh.
|
|
||||||
*/
|
|
||||||
shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
|
|
||||||
#ifdef HAVE_LOGIN_CAP
|
|
||||||
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize the environment. */
|
/* Initialize the environment. */
|
||||||
envsize = 100;
|
envsize = 100;
|
||||||
|
@ -1060,7 +940,7 @@ do_child(Session *s, const char *command)
|
||||||
while (custom_environment) {
|
while (custom_environment) {
|
||||||
struct envstring *ce = custom_environment;
|
struct envstring *ce = custom_environment;
|
||||||
char *s = ce->s;
|
char *s = ce->s;
|
||||||
int i;
|
|
||||||
for (i = 0; s[i] != '=' && s[i]; i++)
|
for (i = 0; s[i] != '=' && s[i]; i++)
|
||||||
;
|
;
|
||||||
if (s[i] == '=') {
|
if (s[i] == '=') {
|
||||||
|
@ -1074,7 +954,7 @@ do_child(Session *s, const char *command)
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, "%.50s %d %d",
|
snprintf(buf, sizeof buf, "%.50s %d %d",
|
||||||
get_remote_ipaddr(), get_remote_port(), get_local_port());
|
get_remote_ipaddr(), get_remote_port(), get_local_port());
|
||||||
child_set_env(&env, &envsize, "SSH_CLIENT", buf);
|
child_set_env(&env, &envsize, "SSH_CLIENT", buf);
|
||||||
|
|
||||||
if (s->ttyfd != -1)
|
if (s->ttyfd != -1)
|
||||||
|
@ -1125,6 +1005,206 @@ do_child(Session *s, const char *command)
|
||||||
for (i = 0; env[i]; i++)
|
for (i = 0; env[i]; i++)
|
||||||
fprintf(stderr, " %.200s\n", env[i]);
|
fprintf(stderr, " %.200s\n", env[i]);
|
||||||
}
|
}
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
|
||||||
|
* first in this order).
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
do_rc_files(Session *s, const char *shell)
|
||||||
|
{
|
||||||
|
FILE *f = NULL;
|
||||||
|
char cmd[1024];
|
||||||
|
int do_xauth;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
do_xauth =
|
||||||
|
s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
|
||||||
|
|
||||||
|
/* ignore _PATH_SSH_USER_RC for subsystems */
|
||||||
|
if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
|
||||||
|
snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
|
||||||
|
shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
|
||||||
|
if (debug_flag)
|
||||||
|
fprintf(stderr, "Running %s\n", cmd);
|
||||||
|
f = popen(cmd, "w");
|
||||||
|
if (f) {
|
||||||
|
if (do_xauth)
|
||||||
|
fprintf(f, "%s %s\n", s->auth_proto,
|
||||||
|
s->auth_data);
|
||||||
|
pclose(f);
|
||||||
|
} else
|
||||||
|
fprintf(stderr, "Could not run %s\n",
|
||||||
|
_PATH_SSH_USER_RC);
|
||||||
|
} else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
|
||||||
|
if (debug_flag)
|
||||||
|
fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
|
||||||
|
_PATH_SSH_SYSTEM_RC);
|
||||||
|
f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
|
||||||
|
if (f) {
|
||||||
|
if (do_xauth)
|
||||||
|
fprintf(f, "%s %s\n", s->auth_proto,
|
||||||
|
s->auth_data);
|
||||||
|
pclose(f);
|
||||||
|
} else
|
||||||
|
fprintf(stderr, "Could not run %s\n",
|
||||||
|
_PATH_SSH_SYSTEM_RC);
|
||||||
|
} else if (do_xauth && options.xauth_location != NULL) {
|
||||||
|
/* Add authority data to .Xauthority if appropriate. */
|
||||||
|
if (debug_flag) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Running %.100s add "
|
||||||
|
"%.100s %.100s %.100s\n",
|
||||||
|
options.xauth_location, s->auth_display,
|
||||||
|
s->auth_proto, s->auth_data);
|
||||||
|
}
|
||||||
|
snprintf(cmd, sizeof cmd, "%s -q -",
|
||||||
|
options.xauth_location);
|
||||||
|
f = popen(cmd, "w");
|
||||||
|
if (f) {
|
||||||
|
fprintf(f, "add %s %s %s\n",
|
||||||
|
s->auth_display, s->auth_proto,
|
||||||
|
s->auth_data);
|
||||||
|
pclose(f);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Could not run %s\n",
|
||||||
|
cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_nologin(struct passwd *pw)
|
||||||
|
{
|
||||||
|
FILE *f = NULL;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
#ifdef HAVE_LOGIN_CAP
|
||||||
|
if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
|
||||||
|
f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
|
||||||
|
_PATH_NOLOGIN), "r");
|
||||||
|
#else
|
||||||
|
if (pw->pw_uid)
|
||||||
|
f = fopen(_PATH_NOLOGIN, "r");
|
||||||
|
#endif
|
||||||
|
if (f) {
|
||||||
|
/* /etc/nologin exists. Print its contents and exit. */
|
||||||
|
while (fgets(buf, sizeof(buf), f))
|
||||||
|
fputs(buf, stderr);
|
||||||
|
fclose(f);
|
||||||
|
exit(254);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set login name, uid, gid, and groups. */
|
||||||
|
static void
|
||||||
|
do_setusercontext(struct passwd *pw)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_CYGWIN
|
||||||
|
if (iswinnt) {
|
||||||
|
#else /* HAVE_CYGWIN */
|
||||||
|
if (getuid() == 0 || geteuid() == 0) {
|
||||||
|
#endif /* HAVE_CYGWIN */
|
||||||
|
#ifdef HAVE_GETUSERATTR
|
||||||
|
set_limits_from_userattr(pw->pw_name);
|
||||||
|
#endif /* HAVE_GETUSERATTR */
|
||||||
|
#ifdef HAVE_LOGIN_CAP
|
||||||
|
if (setusercontext(lc, pw, pw->pw_uid,
|
||||||
|
(LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
|
||||||
|
perror("unable to set user context");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# if defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
|
||||||
|
/* Sets login uid for accounting */
|
||||||
|
if (getluid() == -1 && setluid(pw->pw_uid) == -1)
|
||||||
|
error("setluid: %s", strerror(errno));
|
||||||
|
# endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */
|
||||||
|
|
||||||
|
if (setlogin(pw->pw_name) < 0)
|
||||||
|
error("setlogin failed: %s", strerror(errno));
|
||||||
|
if (setgid(pw->pw_gid) < 0) {
|
||||||
|
perror("setgid");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* Initialize the group list. */
|
||||||
|
if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
|
||||||
|
perror("initgroups");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
endgrent();
|
||||||
|
# ifdef USE_PAM
|
||||||
|
/*
|
||||||
|
* PAM credentials may take the form of supplementary groups.
|
||||||
|
* These will have been wiped by the above initgroups() call.
|
||||||
|
* Reestablish them here.
|
||||||
|
*/
|
||||||
|
do_pam_setcred(0);
|
||||||
|
# endif /* USE_PAM */
|
||||||
|
# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
|
||||||
|
irix_setusercontext(pw);
|
||||||
|
# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
|
||||||
|
#ifdef _AIX
|
||||||
|
aix_usrinfo(s)
|
||||||
|
#endif
|
||||||
|
/* Permanently switch to the desired uid. */
|
||||||
|
permanently_set_uid(pw);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
|
||||||
|
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Performs common processing for the child, such as setting up the
|
||||||
|
* environment, closing extra file descriptors, setting the user and group
|
||||||
|
* ids, and executing the command or shell.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
do_child(Session *s, const char *command)
|
||||||
|
{
|
||||||
|
extern char **environ;
|
||||||
|
char **env;
|
||||||
|
char *argv[10];
|
||||||
|
const char *shell, *shell0, *hostname = NULL;
|
||||||
|
struct passwd *pw = s->pw;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
/* remove hostkey from the child's memory */
|
||||||
|
destroy_sensitive_data();
|
||||||
|
|
||||||
|
/* login(1) is only called if we execute the login shell */
|
||||||
|
if (options.use_login && command != NULL)
|
||||||
|
options.use_login = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Login(1) does this as well, and it needs uid 0 for the "-h"
|
||||||
|
* switch, so we let login(1) to this for us.
|
||||||
|
*/
|
||||||
|
if (!options.use_login) {
|
||||||
|
#ifdef HAVE_OSF_SIA
|
||||||
|
session_setup_sia(pw->pw_name, s->ttyfd == -1 ? NULL : s->tty);
|
||||||
|
if (!check_quietlogin(s, command))
|
||||||
|
do_motd();
|
||||||
|
#else /* HAVE_OSF_SIA */
|
||||||
|
do_nologin(pw);
|
||||||
|
do_setusercontext(pw);
|
||||||
|
#endif /* HAVE_OSF_SIA */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the shell from the password data. An empty shell field is
|
||||||
|
* legal, and means /bin/sh.
|
||||||
|
*/
|
||||||
|
shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
|
||||||
|
#ifdef HAVE_LOGIN_CAP
|
||||||
|
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
env = do_setup_env(s, shell);
|
||||||
|
|
||||||
/* we have to stash the hostname before we close our socket. */
|
/* we have to stash the hostname before we close our socket. */
|
||||||
if (options.use_login)
|
if (options.use_login)
|
||||||
hostname = get_remote_name_or_ip(utmp_len,
|
hostname = get_remote_name_or_ip(utmp_len,
|
||||||
|
@ -1192,114 +1272,65 @@ do_child(Session *s, const char *command)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (!options.use_login)
|
||||||
* Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
|
do_rc_files(s, shell);
|
||||||
* first in this order).
|
|
||||||
*/
|
|
||||||
if (!options.use_login) {
|
|
||||||
/* ignore _PATH_SSH_USER_RC for subsystems */
|
|
||||||
if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
|
|
||||||
snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
|
|
||||||
shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
|
|
||||||
if (debug_flag)
|
|
||||||
fprintf(stderr, "Running %s\n", cmd);
|
|
||||||
f = popen(cmd, "w");
|
|
||||||
if (f) {
|
|
||||||
if (do_xauth)
|
|
||||||
fprintf(f, "%s %s\n", s->auth_proto,
|
|
||||||
s->auth_data);
|
|
||||||
pclose(f);
|
|
||||||
} else
|
|
||||||
fprintf(stderr, "Could not run %s\n",
|
|
||||||
_PATH_SSH_USER_RC);
|
|
||||||
} else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
|
|
||||||
if (debug_flag)
|
|
||||||
fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
|
|
||||||
_PATH_SSH_SYSTEM_RC);
|
|
||||||
f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
|
|
||||||
if (f) {
|
|
||||||
if (do_xauth)
|
|
||||||
fprintf(f, "%s %s\n", s->auth_proto,
|
|
||||||
s->auth_data);
|
|
||||||
pclose(f);
|
|
||||||
} else
|
|
||||||
fprintf(stderr, "Could not run %s\n",
|
|
||||||
_PATH_SSH_SYSTEM_RC);
|
|
||||||
} else if (do_xauth && options.xauth_location != NULL) {
|
|
||||||
/* Add authority data to .Xauthority if appropriate. */
|
|
||||||
if (debug_flag) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Running %.100s add "
|
|
||||||
"%.100s %.100s %.100s\n",
|
|
||||||
options.xauth_location, s->auth_display,
|
|
||||||
s->auth_proto, s->auth_data);
|
|
||||||
}
|
|
||||||
snprintf(cmd, sizeof cmd, "%s -q -",
|
|
||||||
options.xauth_location);
|
|
||||||
f = popen(cmd, "w");
|
|
||||||
if (f) {
|
|
||||||
fprintf(f, "add %s %s %s\n",
|
|
||||||
s->auth_display, s->auth_proto,
|
|
||||||
s->auth_data);
|
|
||||||
pclose(f);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Could not run %s\n",
|
|
||||||
cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Get the last component of the shell name. */
|
|
||||||
cp = strrchr(shell, '/');
|
|
||||||
if (cp)
|
|
||||||
cp++;
|
|
||||||
else
|
|
||||||
cp = shell;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* restore SIGPIPE for child */
|
/* restore SIGPIPE for child */
|
||||||
signal(SIGPIPE, SIG_DFL);
|
signal(SIGPIPE, SIG_DFL);
|
||||||
|
|
||||||
|
if (options.use_login) {
|
||||||
|
/* Launch login(1). */
|
||||||
|
|
||||||
|
execl(LOGIN_PROGRAM, "login", "-h", hostname,
|
||||||
|
#ifdef LOGIN_NEEDS_TERM
|
||||||
|
(s->term ? s->term : "unknown"),
|
||||||
|
#endif /* LOGIN_NEEDS_TERM */
|
||||||
|
"-p", "-f", "--", pw->pw_name, (char *)NULL);
|
||||||
|
|
||||||
|
/* Login couldn't be executed, die. */
|
||||||
|
|
||||||
|
perror("login");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the last component of the shell name. */
|
||||||
|
if ((shell0 = strrchr(shell, '/')) != NULL)
|
||||||
|
shell0++;
|
||||||
|
else
|
||||||
|
shell0 = shell;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have no command, execute the shell. In this case, the shell
|
* If we have no command, execute the shell. In this case, the shell
|
||||||
* name to be passed in argv[0] is preceded by '-' to indicate that
|
* name to be passed in argv[0] is preceded by '-' to indicate that
|
||||||
* this is a login shell.
|
* this is a login shell.
|
||||||
*/
|
*/
|
||||||
if (!command) {
|
if (!command) {
|
||||||
if (!options.use_login) {
|
char argv0[256];
|
||||||
char buf[256];
|
|
||||||
|
|
||||||
/* Start the shell. Set initial character to '-'. */
|
/* Start the shell. Set initial character to '-'. */
|
||||||
buf[0] = '-';
|
argv0[0] = '-';
|
||||||
strlcpy(buf + 1, cp, sizeof(buf) - 1);
|
|
||||||
|
|
||||||
/* Execute the shell. */
|
if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1)
|
||||||
argv[0] = buf;
|
>= sizeof(argv0) - 1) {
|
||||||
argv[1] = NULL;
|
errno = EINVAL;
|
||||||
execve(shell, argv, env);
|
|
||||||
|
|
||||||
/* Executing the shell failed. */
|
|
||||||
perror(shell);
|
perror(shell);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
} else {
|
|
||||||
/* Launch login(1). */
|
|
||||||
|
|
||||||
execl(LOGIN_PROGRAM, "login", "-h", hostname,
|
|
||||||
#ifdef LOGIN_NEEDS_TERM
|
|
||||||
s->term? s->term : "unknown",
|
|
||||||
#endif
|
|
||||||
"-p", "-f", "--", pw->pw_name, (char *)NULL);
|
|
||||||
|
|
||||||
/* Login couldn't be executed, die. */
|
|
||||||
|
|
||||||
perror("login");
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Execute the shell. */
|
||||||
|
argv[0] = argv0;
|
||||||
|
argv[1] = NULL;
|
||||||
|
execve(shell, argv, env);
|
||||||
|
|
||||||
|
/* Executing the shell failed. */
|
||||||
|
perror(shell);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Execute the command using the user's shell. This uses the -c
|
* Execute the command using the user's shell. This uses the -c
|
||||||
* option to execute the command.
|
* option to execute the command.
|
||||||
*/
|
*/
|
||||||
argv[0] = (char *) cp;
|
argv[0] = (char *) shell0;
|
||||||
argv[1] = "-c";
|
argv[1] = "-c";
|
||||||
argv[2] = (char *) command;
|
argv[2] = (char *) command;
|
||||||
argv[3] = NULL;
|
argv[3] = NULL;
|
||||||
|
|
Loading…
Reference in New Issue