Bug#48057: scp -r follows symlinks
I wrote a patch to fix this problem. I has not been toroughly tested
and it may not apply anymore but it may help some people.
It has been marked as WONTFIX in the OpenSSH Bugzilla.
http://bugzilla.mindrot.org/show_bug.cgi?id=1059
http://openssh.org/faq.html#2.10
Of course nobody is supposed to use scp anymore :)
# Adds an -s option to scp(1) to ignore symlinks.
# Applies to scp.c 1.124 (that's -current from 17 June 2005)
# Patch submitted as part of bugreport #1059 (attachment #933) on 1 July 2005,
# rejected on 12 July 2006.
# http://bugzilla.mindrot.org/show_bug.cgi?id=1059
diff -ur ssh.old/scp.1 ssh/scp.1
--- ssh.old/scp.1 2005-06-30 18:40:29.116463608 +0200
+++ ssh/scp.1 2005-06-30 18:41:12.493869240 +0200
@@ -20,7 +20,7 @@
.Sh SYNOPSIS
.Nm scp
.Bk -words
-.Op Fl 1246BCpqrv
+.Op Fl 1246BCpqrsv
.Op Fl c Ar cipher
.Op Fl F Ar ssh_config
.Op Fl i Ar identity_file
@@ -180,6 +180,8 @@
Disables the progress meter.
.It Fl r
Recursively copy entire directories.
+.It Fl s
+Ignore symbolic links.
.It Fl S Ar program
Name of
.Ar program
@@ -218,3 +220,4 @@
.Sh AUTHORS
.An Timo Rinne Aq tri@iki.fi
.An Tatu Ylonen Aq ylo@cs.hut.fi
+.An Adrien Kunysz (for the -s option) Aq a_kunysz@yahoo.com
diff -ur ssh.old/scp.c ssh/scp.c
--- ssh.old/scp.c 2005-06-30 18:40:29.117463456 +0200
+++ ssh/scp.c 2005-06-30 18:41:12.532863312 +0200
@@ -200,10 +200,10 @@
struct passwd *pwd;
uid_t userid;
int errs, remin, remout;
-int pflag, iamremote, iamrecursive, targetshouldbedirectory;
+int pflag, iamremote, iamrecursive, targetshouldbedirectory, ignorelinks;
#define CMDNEEDS 64
-char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */
+char cmd[CMDNEEDS]; /* must hold "scp -v -r -p -s -d\0" */
int response(void);
void rsource(char *, struct stat *);
@@ -229,7 +229,7 @@
addargs(&args, "-oClearAllForwardings yes");
fflag = tflag = 0;
- while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1)
+ while ((ch = getopt(argc, argv, "dfl:prstvBCc:i:P:q1246S:o:F:")) != -1)
switch (ch) {
/* User-visible flags. */
case '1':
@@ -263,6 +263,9 @@
case 'r':
iamrecursive = 1;
break;
+ case 's':
+ ignorelinks = 1;
+ break;
case 'S':
ssh_program = xstrdup(optarg);
break;
@@ -321,9 +324,10 @@
remin = remout = -1;
do_cmd_pid = -1;
/* Command to be executed on remote system using "ssh". */
- (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s",
+ (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s%s",
verbose_mode ? " -v" : "",
- iamrecursive ? " -r" : "", pflag ? " -p" : "",
+ iamrecursive ? " -r" : "", ignorelinks ? " -s" : "",
+ pflag ? " -p" : "",
targetshouldbedirectory ? " -d" : "");
(void) signal(SIGPIPE, lostconn);
@@ -455,8 +459,9 @@
len = strlen(_PATH_CP) + strlen(argv[i]) +
strlen(argv[argc - 1]) + 20;
bp = xmalloc(len);
- (void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,
- iamrecursive ? " -r" : "", pflag ? " -p" : "",
+ (void)snprintf(bp, len, "exec %s%s%s%s %s %s", _PATH_CP,
+ iamrecursive ? " -r" : "", ignorelinks ? " -s" : "",
+ pflag ? " -p" : "",
argv[i], argv[argc - 1]);
if (verbose_mode)
fprintf(stderr, "Executing: %s\n", bp);
@@ -516,6 +521,12 @@
name);
goto next;
}
+ if (ignorelinks) {
+ if (lstat(name, &stb) < 0)
+ goto syserr;
+ if (S_ISLNK(stb.st_mode))
+ goto next;
+ }
if ((fd = open(name, O_RDONLY, 0)) < 0)
goto syserr;
if (fstat(fd, &stb) < 0) {
@@ -1019,7 +1030,7 @@
usage(void)
{
(void) fprintf(stderr,
- "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
+ "usage: scp [-1246BCpqrsv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
" [-l limit] [-o ssh_option] [-P port] [-S program]\n"
" [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
exit(1);
Reply to: