]> git.wh0rd.org - dump.git/commitdiff
Added the RSH variable to specify a replacement for build-in rcmd
authorStelian Pop <stelian@popies.net>
Sat, 30 Oct 1999 22:55:45 +0000 (22:55 +0000)
committerStelian Pop <stelian@popies.net>
Sat, 30 Oct 1999 22:55:45 +0000 (22:55 +0000)
CHANGES
common/dumprmt.c
dump/dump.8.in
restore/restore.8.in

diff --git a/CHANGES b/CHANGES
index d098293dd93110702489f879c8156df787541b0d..7f99d5fb5c2f04916e23321b2bd19fc2eab94509 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-$Id: CHANGES,v 1.8 1999/10/22 18:12:25 tiniou Exp $
+$Id: CHANGES,v 1.9 1999/10/30 22:55:45 tiniou Exp $
 
 Changes between versions 0.4b7 and 0.4b8 (released ???????????????)
 ===================================================================
@@ -17,6 +17,11 @@ Changes between versions 0.4b7 and 0.4b8 (released ???????????????)
        contain them :(. Thanks to Eric Maisonobe <virnet@nat.fr>
        for submitting the bug report.
 
+5.     Added the RSH environment variable in order to be able to
+       use a rsh replacement like ssh when doing remote backups (and
+       bypass the security limitations of rcmd). Now you can do remote
+       backups without being root (or making dump setuid root).
+
 Changes between versions 0.4b6 and 0.4b7 (released October 8, 1999)
 ===================================================================
 
index 4caedfa3384804c3f8ccd6b0f137cd85ac270479..db18d328547cb717a37cc586b04b950d68313c62 100644 (file)
@@ -40,7 +40,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: dumprmt.c,v 1.6 1999/10/13 09:57:18 stelian Exp $";
+       "$Id: dumprmt.c,v 1.7 1999/10/30 22:55:50 tiniou Exp $";
 #endif /* not lint */
 
 #ifdef __linux__
@@ -95,16 +95,18 @@ static const char rcsid[] =
 #define        TS_OPEN         1
 
 static int rmtstate = TS_CLOSED;
-static int rmtape = -1;
+static int tormtape = -1;
+static int fromrmtape = -1;
 static const char *rmtpeer = 0;
 
 static int okname __P((const char *));
 static int rmtcall __P((const char *, const char *));
 static void rmtconnaborted __P((int));
 static int rmtgetb __P((void));
-static void rmtgetconn __P((void));
+static int rmtgetconn __P((void));
 static void rmtgets __P((char *, size_t));
 static int rmtreply __P((const char *));
+static  int piped_child __P((const char **command));
 #ifdef KERBEROS
 int    krcmd __P((char **, int /*u_short*/, char *, char *, int *, char *));
 #endif
@@ -124,10 +126,7 @@ rmthost(const char *host)
        if ((rmtpeer = strdup(host)) == NULL)
                rmtpeer = host;
        signal(SIGPIPE, rmtconnaborted);
-       rmtgetconn();
-       if (rmtape < 0)
-               return (0);
-       return (1);
+       return rmtgetconn();
 }
 
 static void
@@ -157,7 +156,7 @@ rmtconnaborted(int signo)
        exit(X_ABORT);
 }
 
-static void
+static int
 rmtgetconn(void)
 {
        register char *cp;
@@ -165,15 +164,20 @@ rmtgetconn(void)
        static struct servent *sp = NULL;
        static struct passwd *pwd = NULL;
        const char *tuser;
+       const char *rsh;
        int size;
        int throughput;
        int on;
 
-       if (sp == NULL) {
+       rsh = getenv("RSH");
+
+       if (!rsh && sp == NULL) {
                sp = getservbyname(dokerberos ? "kshell" : "shell", "tcp");
                if (sp == NULL)
                        errx(1, "%s/tcp: unknown service",
                            dokerberos ? "kshell" : "shell");
+       }
+       if (pwd == NULL) {
                pwd = getpwuid(getuid());
                if (pwd == NULL)
                        errx(1, "who are you?");
@@ -189,35 +193,54 @@ rmtgetconn(void)
        if ((rmt = getenv("RMT")) == NULL)
                rmt = _PATH_RMT;
        msg("");
+
+       if (rsh) {
+               const char *rshcmd[6];
+               rshcmd[0] = rsh;
+               rshcmd[1] = rmtpeer;
+               rshcmd[2] = "-l";
+               rshcmd[3] = tuser;
+               rshcmd[4] = rmt;
+               rshcmd[5] = NULL;
+
+               if (piped_child(rshcmd) < 0) {
+                       msg("cannot open connection\n");
+                       return 0;
+               }
+       }
+       else {
 #ifdef KERBEROS
-       if (dokerberos)
-               rmtape = krcmd((char **)&rmtpeer, sp->s_port, tuser, rmt, &errfd,
-                              (char *)0);
-       else
+               if (dokerberos)
+                       tormtape = krcmd((char **)&rmtpeer, sp->s_port, tuser, rmt, &errfd,
+                                      (char *)0);
+               else
 #endif
-               rmtape = rcmd((char **)&rmtpeer, (u_short)sp->s_port, pwd->pw_name,
-                             tuser, rmt, &errfd);
-       if (rmtape < 0) {
-               msg("login to %s as %s failed.\n", rmtpeer, tuser);
-               return;
+                       tormtape = rcmd((char **)&rmtpeer, (u_short)sp->s_port, pwd->pw_name,
+                                     tuser, rmt, &errfd);
+               if (tormtape < 0) {
+                       msg("login to %s as %s failed.\n", rmtpeer, tuser);
+                       return 0;
+               }
+               size = ntrec * TP_BSIZE;
+               if (size > 60 * 1024)           /* XXX */
+                       size = 60 * 1024;
+               /* Leave some space for rmt request/response protocol */
+               size += 2 * 1024;
+               while (size > TP_BSIZE &&
+                   setsockopt(tormtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
+                           size -= TP_BSIZE;
+               (void)setsockopt(tormtape, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
+               throughput = IPTOS_THROUGHPUT;
+               if (setsockopt(tormtape, IPPROTO_IP, IP_TOS,
+                   &throughput, sizeof(throughput)) < 0)
+                       perror("IP_TOS:IPTOS_THROUGHPUT setsockopt");
+               on = 1;
+               if (setsockopt(tormtape, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on)) < 0)
+                       perror("TCP_NODELAY setsockopt");
+               fromrmtape = tormtape;
        }
        (void)fprintf(stderr, "Connection to %s established.\n", rmtpeer);
-       size = ntrec * TP_BSIZE;
-       if (size > 60 * 1024)           /* XXX */
-               size = 60 * 1024;
-       /* Leave some space for rmt request/response protocol */
-       size += 2 * 1024;
-       while (size > TP_BSIZE &&
-           setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
-                   size -= TP_BSIZE;
-       (void)setsockopt(rmtape, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
-       throughput = IPTOS_THROUGHPUT;
-       if (setsockopt(rmtape, IPPROTO_IP, IP_TOS,
-           &throughput, sizeof(throughput)) < 0)
-               perror("IP_TOS:IPTOS_THROUGHPUT setsockopt");
-       on = 1;
-       if (setsockopt(rmtape, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on)) < 0)
-               perror("TCP_NODELAY setsockopt");
+       return 1;
 }
 
 static int
@@ -269,7 +292,7 @@ rmtread(char *buf, size_t count)
                /* rmtcall() properly sets errno for us on errors. */
                return (n);
        for (i = 0; i < n; i += cc) {
-               cc = read(rmtape, buf+i, n - i);
+               cc = read(fromrmtape, buf+i, n - i);
                if (cc <= 0)
                        rmtconnaborted(0);
        }
@@ -282,8 +305,8 @@ rmtwrite(const char *buf, size_t count)
        char line[30];
 
        (void)snprintf(line, sizeof (line), "W%d\n", count);
-       write(rmtape, line, strlen(line));
-       write(rmtape, buf, count);
+       write(tormtape, line, strlen(line));
+       write(tormtape, buf, count);
        return (rmtreply("write"));
 }
 
@@ -327,7 +350,7 @@ static int
 rmtcall(const char *cmd, const char *buf)
 {
 
-       if (write(rmtape, buf, strlen(buf)) != strlen(buf))
+       if (write(tormtape, buf, strlen(buf)) != strlen(buf))
                rmtconnaborted(0);
        return (rmtreply(cmd));
 }
@@ -365,7 +388,7 @@ rmtgetb(void)
 {
        char c;
 
-       if (read(rmtape, &c, 1) != 1)
+       if (read(fromrmtape, &c, 1) != 1)
                rmtconnaborted(0);
        return (c);
 }
@@ -390,3 +413,55 @@ rmtgets(char *line, size_t len)
        msg("(rmtgets got \"%s\").\n", line);
        rmtconnaborted(0);
 }
+
+int piped_child(const char **command) {
+       int pid;
+       int to_child_pipe[2];
+       int from_child_pipe[2];
+
+       if (pipe (to_child_pipe) < 0) {
+               msg ("cannot create pipe: %s\n", strerror(errno));
+               return -1;
+       }
+       if (pipe (from_child_pipe) < 0) {
+               msg ("cannot create pipe: %s\n", strerror(errno)); 
+               return -1;
+       }
+       pid = fork ();
+       if (pid < 0) {
+               msg ("cannot fork: %s\n", strerror(errno));
+               return -1;
+       }
+       if (pid == 0) {
+               if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0) {
+                       msg ("cannot dup2 pipe: %s\n", strerror(errno));
+                       exit(1);
+               }
+               if (close (to_child_pipe[1]) < 0) {
+                       msg ("cannot close pipe: %s\n", strerror(errno));
+                       exit(1);
+               }
+               if (close (from_child_pipe[0]) < 0) {
+                       msg ("cannot close pipe: %s\n", strerror(errno));
+                       exit(1);
+               }
+               if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0) {
+                       msg ("cannot dup2 pipe: %s\n", strerror(errno));
+                       exit(1);
+               }
+               execvp (command[0], (char *const *) command);
+               msg("cannot exec %s: %s\n", command[0], strerror(errno));
+               exit(1);
+       }
+       if (close (to_child_pipe[0]) < 0) {
+               msg ("cannot close pipe: %s\n", strerror(errno));
+               return -1;
+       }
+       if (close (from_child_pipe[1]) < 0) {
+               msg ("cannot close pipe: %s\n", strerror(errno));
+               return -1;
+       }
+       tormtape = to_child_pipe[1];
+       fromrmtape = from_child_pipe[0];
+       return pid;
+}
index 67fab473e46372a341dbbc9cf4efd894320e4bde..3fa63c102cb54988ab1ffd0d24762d518e1714c7 100644 (file)
@@ -30,7 +30,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"    $Id: dump.8.in,v 1.3 1999/10/13 09:57:19 stelian Exp $
+.\"    $Id: dump.8.in,v 1.4 1999/10/30 22:55:51 tiniou Exp $
 .\"
 .Dd __DATE__
 .Dt DUMP 8
@@ -380,6 +380,13 @@ The environment variable
 will be used to determine the pathname of the remote
 .Xr rmt 8
 program.
+.It Ev RSH
+.Nm Dump
+uses the contents of this variable to determine the name of the
+remote shell command to use when doing remote backups (rsh, ssh etc.). 
+If this variable is not set, 
+.Xr rcmd 3
+will be used, but only root will be able to do remote backups.
 .Sh FILES
 .Bl -tag -width __DUMPDATES__ -compact
 .It Pa /dev/st0
@@ -437,10 +444,10 @@ for the operator running
 .Pp
 .Nm Dump
 cannot do remote backups without being run as root, due to its
-security history.  This will be fixed in a later version of
-.Bx Free .
+security history.
 Presently, it works if you set it setuid (like it used to be), but this
-might constitute a security risk.
+might constitute a security risk. Note that you can set RSH to use
+a remote shell program instead.
 .Sh AUTHOR
 The 
 .Nm dump/restore
index 712dcf467b01e74f8177019145cf482da127af71..c25c8c70a6e2b955809c2b7a9b4a9a3097880372 100644 (file)
@@ -29,7 +29,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"    $Id: restore.8.in,v 1.3 1999/10/13 09:57:21 stelian Exp $
+.\"    $Id: restore.8.in,v 1.4 1999/10/30 22:55:51 tiniou Exp $
 .\"
 .Dd __DATE__
 .Dt RESTORE 8
@@ -478,6 +478,13 @@ The environment variable
 will be used to determine the pathname of the remote
 .Xr rmt 8
 program.
+.It Ev RSH
+.Nm Restore
+uses the contents of this variable to determine the name of the
+remote shell command to use when doing a network restore (rsh, ssh etc.).
+If this variable is not set,
+.Xr rcmd 3
+will be used, but only root will be able to do a network restore.
 .Sh FILES
 .Bl -tag -width "./restoresymtable" -compact
 .It Pa /dev/st0
@@ -530,7 +537,8 @@ In all other cases, the files are unique because it is possible to
 have two different dumps started at the same time, and separate
 operations shouldn't conflict with each other.
 .Pp
-To do a network restore, you have to run restore as root.  This is due
+To do a network restore, you have to run restore as root or use
+a remote shell replacement (see RSH variable).  This is due
 to the previous security history of dump and restore.  (restore is
 written to be setuid root, but we are not certain all bugs are gone
 from the restore code - run setuid at your own risk.)