added the --safe-links option to disallow symlinks outside the

destination tree
This commit is contained in:
Andrew Tridgell
1998-07-17 10:00:48 +00:00
parent d853783f21
commit 4b957c2238
2 changed files with 47 additions and 5 deletions

View File

@@ -315,11 +315,6 @@ option all symbolic links are skipped.
dit(bf(-L, --copy-links)) This tells rsync to treat symbolic links just
like ordinary files.
dit(bf(--safe-links)) This tells rsync to ignore any symbolic links
which point outside the destination tree. All absolute symlinks are
also ignored. Using this option in conjunction with --relative may
give unexpecetd results.
dit(bf(-H, --hard-links)) This tells rsync to recreate hard links on
the remote system to be the same as the local system. Without this
option hard links are treated like regular files.

47
util.c
View File

@@ -710,3 +710,50 @@ void show_progress(OFF_T ofs, OFF_T size)
}
}
}
/* determine if a symlink points outside the current directory tree */
int unsafe_symlink(char *dest, char *src)
{
char *tok;
int depth = 0;
/* all absolute and null symlinks are unsafe */
if (!dest || !(*dest) || (*dest == '/')) return 1;
src = strdup(src);
if (!src) out_of_memory("unsafe_symlink");
/* find out what our safety margin is */
for (tok=strtok(src,"/"); tok; tok=strtok(NULL,"/")) {
if (strcmp(tok,"..") == 0) {
depth=0;
} else if (strcmp(tok,".") == 0) {
/* nothing */
} else {
depth++;
}
}
free(src);
/* drop by one to account for the filename portion */
depth--;
dest = strdup(dest);
if (!dest) out_of_memory("unsafe_symlink");
for (tok=strtok(dest,"/"); tok; tok=strtok(NULL,"/")) {
if (strcmp(tok,"..") == 0) {
depth--;
} else if (strcmp(tok,".") == 0) {
/* nothing */
} else {
depth++;
}
/* if at any point we go outside the current directory then
stop - it is unsafe */
if (depth < 0) break;
}
free(dest);
return (depth < 0);
}