summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/appl/rsh/rshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/appl/rsh/rshd.c')
-rw-r--r--crypto/heimdal/appl/rsh/rshd.c177
1 files changed, 99 insertions, 78 deletions
diff --git a/crypto/heimdal/appl/rsh/rshd.c b/crypto/heimdal/appl/rsh/rshd.c
index 1464fe1..852327a 100644
--- a/crypto/heimdal/appl/rsh/rshd.c
+++ b/crypto/heimdal/appl/rsh/rshd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -32,10 +32,17 @@
*/
#include "rsh_locl.h"
-RCSID("$Id: rshd.c,v 1.51.2.1 2003/08/19 11:36:17 joda Exp $");
+#include "login_locl.h"
+RCSID("$Id: rshd.c 21515 2007-07-12 12:47:07Z lha $");
int
login_access( struct passwd *user, char *from);
+int
+read_limits_conf(const char *file, const struct passwd *pwd);
+
+#ifdef NEED_IRUSEROK_PROTO
+int iruserok(uint32_t, int, const char *, const char *);
+#endif
enum auth_method auth_method;
@@ -74,13 +81,6 @@ static int do_keepalive = 1;
static int do_version;
static int do_help = 0;
-#if defined(KRB5) && defined(DCE)
-int dfsk5ok = 0;
-int dfspag = 0;
-int dfsfwd = 0;
-krb5_ticket *user_ticket;
-#endif
-
static void
syslog_and_die (const char *m, ...)
__attribute__ ((format (printf, 1, 2)));
@@ -263,15 +263,25 @@ static void
krb5_start_session (void)
{
krb5_error_code ret;
+ char *estr;
ret = krb5_cc_resolve (context, tkfile, &ccache2);
if (ret) {
+ estr = krb5_get_error_string(context);
+ syslog(LOG_WARNING, "resolve cred cache %s: %s",
+ tkfile,
+ estr ? estr : krb5_get_err_text(context, ret));
+ free(estr);
krb5_cc_destroy(context, ccache);
return;
}
ret = krb5_cc_copy_cache (context, ccache, ccache2);
if (ret) {
+ estr = krb5_get_error_string(context);
+ syslog(LOG_WARNING, "storing credentials: %s",
+ estr ? estr : krb5_get_err_text(context, ret));
+ free(estr);
krb5_cc_destroy(context, ccache);
return ;
}
@@ -307,12 +317,13 @@ recv_krb5_auth (int s, u_char *buf,
char **server_username,
char **cmd)
{
- u_int32_t len;
+ uint32_t len;
krb5_auth_context auth_context = NULL;
krb5_ticket *ticket;
krb5_error_code status;
krb5_data cksum_data;
krb5_principal server;
+ char *str;
if (memcmp (buf, "\x00\x00\x00\x13", 4) != 0)
return -1;
@@ -371,11 +382,14 @@ recv_krb5_auth (int s, u_char *buf,
krb5_get_err_text(context, status));
- cksum_data.length = asprintf ((char **)&cksum_data.data,
+ cksum_data.length = asprintf (&str,
"%u:%s%s",
ntohs(socket_get_port (thisaddr)),
*cmd,
*server_username);
+ if (str == NULL)
+ syslog_and_die ("asprintf: out of memory");
+ cksum_data.data = str;
status = krb5_verify_authenticator_checksum(context,
auth_context,
@@ -401,12 +415,16 @@ recv_krb5_auth (int s, u_char *buf,
if (strncmp (*client_username + 3, "FILE:", 5) == 0) {
temp_tkfile = tkfile;
} else {
- strcpy (tkfile, "FILE:");
+ strlcpy (tkfile, "FILE:", sizeof(tkfile));
temp_tkfile = tkfile + 5;
}
end = strchr(*client_username + 3,' ');
- strncpy(temp_tkfile, *client_username + 3, end - *client_username - 3);
- temp_tkfile[end - *client_username - 3] = '\0';
+ if (end == NULL)
+ syslog_and_die("missing argument after -U");
+ snprintf(temp_tkfile, sizeof(tkfile) - (temp_tkfile - tkfile),
+ "%.*s",
+ (int)(end - *client_username - 3),
+ *client_username + 3);
memmove (*client_username, end + 1, strlen(end+1)+1);
}
@@ -448,29 +466,27 @@ recv_krb5_auth (int s, u_char *buf,
}
}
-#if defined(DCE)
- user_ticket = ticket;
-#endif
-
return 0;
}
#endif /* KRB5 */
static void
-loop (int from0, int to0,
- int to1, int from1,
- int to2, int from2)
+rshd_loop (int from0, int to0,
+ int to1, int from1,
+ int to2, int from2,
+ int have_errsock)
{
fd_set real_readset;
int max_fd;
int count = 2;
+ char *buf;
if(from0 >= FD_SETSIZE || from1 >= FD_SETSIZE || from2 >= FD_SETSIZE)
errx (1, "fd too large");
#ifdef KRB5
if(auth_method == AUTH_KRB5 && protocol_version == 2)
- init_ivecs(0);
+ init_ivecs(0, have_errsock);
#endif
FD_ZERO(&real_readset);
@@ -478,10 +494,14 @@ loop (int from0, int to0,
FD_SET(from1, &real_readset);
FD_SET(from2, &real_readset);
max_fd = max(from0, max(from1, from2)) + 1;
+
+ buf = malloc(max(RSHD_BUFSIZ, RSH_BUFSIZ));
+ if (buf == NULL)
+ syslog_and_die("out of memory");
+
for (;;) {
int ret;
fd_set readset = real_readset;
- char buf[RSH_BUFSIZ];
ret = select (max_fd, &readset, NULL, NULL, NULL);
if (ret < 0) {
@@ -491,7 +511,7 @@ loop (int from0, int to0,
syslog_and_die ("select: %m");
}
if (FD_ISSET(from0, &readset)) {
- ret = do_read (from0, buf, sizeof(buf), ivec_in[0]);
+ ret = do_read (from0, buf, RSHD_BUFSIZ, ivec_in[0]);
if (ret < 0)
syslog_and_die ("read: %m");
else if (ret == 0) {
@@ -502,7 +522,7 @@ loop (int from0, int to0,
net_write (to0, buf, ret);
}
if (FD_ISSET(from1, &readset)) {
- ret = read (from1, buf, sizeof(buf));
+ ret = read (from1, buf, RSH_BUFSIZ);
if (ret < 0)
syslog_and_die ("read: %m");
else if (ret == 0) {
@@ -515,7 +535,7 @@ loop (int from0, int to0,
do_write (to1, buf, ret, ivec_out[0]);
}
if (FD_ISSET(from2, &readset)) {
- ret = read (from2, buf, sizeof(buf));
+ ret = read (from2, buf, RSH_BUFSIZ);
if (ret < 0)
syslog_and_die ("read: %m");
else if (ret == 0) {
@@ -551,7 +571,7 @@ pipe_a_like (int fd[2])
* Start a child process and leave the parent copying data to and from it. */
static void
-setup_copier (void)
+setup_copier (int have_errsock)
{
int p0[2], p1[2], p2[2];
pid_t pid;
@@ -580,9 +600,10 @@ setup_copier (void)
if (net_write (STDOUT_FILENO, "", 1) != 1)
fatal (STDOUT_FILENO, "net_write", "Write failure.");
- loop (STDIN_FILENO, p0[1],
+ rshd_loop (STDIN_FILENO, p0[1],
STDOUT_FILENO, p1[0],
- STDERR_FILENO, p2[0]);
+ STDERR_FILENO, p2[0],
+ have_errsock);
}
}
@@ -621,20 +642,20 @@ setup_environment (char ***env, const struct passwd *pwd)
e = *env;
e = realloc(e, (i + 7) * sizeof(char *));
- asprintf (&e[i++], "USER=%s", pwd->pw_name);
- asprintf (&e[i++], "HOME=%s", pwd->pw_dir);
- asprintf (&e[i++], "SHELL=%s", pwd->pw_shell);
+ if (asprintf (&e[i++], "USER=%s", pwd->pw_name) == -1)
+ syslog_and_die ("asprintf: out of memory");
+ if (asprintf (&e[i++], "HOME=%s", pwd->pw_dir) == -1)
+ syslog_and_die ("asprintf: out of memory");
+ if (asprintf (&e[i++], "SHELL=%s", pwd->pw_shell) == -1)
+ syslog_and_die ("asprintf: out of memory");
if (! path) {
- asprintf (&e[i++], "PATH=%s", _PATH_DEFPATH);
+ if (asprintf (&e[i++], "PATH=%s", _PATH_DEFPATH) == -1)
+ syslog_and_die ("asprintf: out of memory");
}
asprintf (&e[i++], "SSH_CLIENT=only_to_make_bash_happy");
-#if defined(DCE)
- if (getenv("KRB5CCNAME"))
- asprintf (&e[i++], "KRB5CCNAME=%s", getenv("KRB5CCNAME"));
-#else
if (do_unique_tkfile)
- asprintf (&e[i++], "KRB5CCNAME=%s", tkfile);
-#endif
+ if (asprintf (&e[i++], "KRB5CCNAME=%s", tkfile) == -1)
+ syslog_and_die ("asprintf: out of memory");
e[i++] = NULL;
*env = e;
}
@@ -653,7 +674,7 @@ doit (void)
socklen_t thisaddr_len, thataddr_len;
int port;
int errsock = -1;
- char *client_user, *server_user, *cmd;
+ char *client_user = NULL, *server_user = NULL, *cmd = NULL;
struct passwd *pwd;
int s = STDIN_FILENO;
char **env;
@@ -760,9 +781,8 @@ doit (void)
syslog_and_die("recv_bsd_auth failed");
}
-#if defined(DCE) && defined(_AIX)
- esetenv("AUTHSTATE", "DCE", 1);
-#endif
+ if (client_user == NULL || server_user == NULL || cmd == NULL)
+ syslog_and_die("mising client/server/cmd");
pwd = getpwnam (server_user);
if (pwd == NULL)
@@ -803,33 +823,6 @@ doit (void)
#endif
-#ifdef KRB5
- {
- int fd;
-
- if (!do_unique_tkfile)
- snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_%u",pwd->pw_uid);
- else if (*tkfile=='\0') {
- snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_XXXXXX");
- fd = mkstemp(tkfile+5);
- close(fd);
- unlink(tkfile+5);
- }
-
- if (kerberos_status)
- krb5_start_session();
- }
- chown(tkfile + 5, pwd->pw_uid, -1);
-
-#if defined(DCE)
- if (kerberos_status) {
- esetenv("KRB5CCNAME", tkfile, 1);
- dfspag = krb5_dfs_pag(context, kerberos_status, user_ticket->client, server_user);
- }
-#endif
-
-#endif
-
#ifdef HAVE_SETLOGIN
if (setlogin(pwd->pw_name) < 0)
syslog(LOG_ERR, "setlogin() failed: %m");
@@ -840,6 +833,12 @@ doit (void)
syslog(LOG_ERR, "setpcred() failure: %m");
#endif /* HAVE_SETPCRED */
+ /* Apply limits if not root */
+ if(pwd->pw_uid != 0) {
+ const char *file = _PATH_LIMITS_CONF;
+ read_limits_conf(file, pwd);
+ }
+
if (initgroups (pwd->pw_name, pwd->pw_gid) < 0)
fatal (s, "initgroups", "Login incorrect.");
@@ -856,12 +855,34 @@ doit (void)
if (dup2 (errsock, STDERR_FILENO) < 0)
fatal (s, "dup2", "Cannot dup stderr.");
close (errsock);
+ } else {
+ if (dup2 (STDOUT_FILENO, STDERR_FILENO) < 0)
+ fatal (s, "dup2", "Cannot dup stderr.");
}
+#ifdef KRB5
+ {
+ int fd;
+
+ if (!do_unique_tkfile)
+ snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_%lu",
+ (unsigned long)pwd->pw_uid);
+ else if (*tkfile=='\0') {
+ snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_XXXXXX");
+ fd = mkstemp(tkfile+5);
+ close(fd);
+ unlink(tkfile+5);
+ }
+
+ if (kerberos_status)
+ krb5_start_session();
+ }
+#endif
+
setup_environment (&env, pwd);
if (do_encrypt) {
- setup_copier ();
+ setup_copier (errsock >= 0);
} else {
if (net_write (s, "", 1) != 1)
fatal (s, "net_write", "write failed");
@@ -972,13 +993,6 @@ main(int argc, char **argv)
do_kerberos = DO_KRB4 | DO_KRB5;
#endif
- if (do_keepalive &&
- setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
- sizeof(on)) < 0)
- syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
-
- /* set SO_LINGER? */
-
#ifdef KRB5
if((do_kerberos & DO_KRB5) && krb5_init_context (&context) != 0)
do_kerberos &= ~DO_KRB5;
@@ -1035,6 +1049,13 @@ main(int argc, char **argv)
freeaddrinfo(ai);
}
+ if (do_keepalive &&
+ setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
+ sizeof(on)) < 0)
+ syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
+
+ /* set SO_LINGER? */
+
signal (SIGPIPE, SIG_IGN);
doit ();
OpenPOWER on IntegriCloud