summaryrefslogtreecommitdiffstats
path: root/lib/libarchive/archive_write_disk.c
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2008-09-07 05:22:33 +0000
committerkientzle <kientzle@FreeBSD.org>2008-09-07 05:22:33 +0000
commit02ce672bbc07905ebf44d957200a6c633201dee0 (patch)
treedf85ea1bd1ac4ccee68e04cd8ab5d3e7c64d03f8 /lib/libarchive/archive_write_disk.c
parent5272b43e206a1641c3638e71e7068d76e9eaf194 (diff)
downloadFreeBSD-src-02ce672bbc07905ebf44d957200a6c633201dee0.zip
FreeBSD-src-02ce672bbc07905ebf44d957200a6c633201dee0.tar.gz
When restoring a directory, allow symlinks to be followed. The full
logic here gets a little complex, but the net effect is that the SECURE_SYMLINKS flag will prevent us from ever following a symlink. Without it, we'll only follow symlinks to dirs. bsdtar specifies SECURE_SYMLINKS by default, suppresses it for -P. I've also beefed up the write_disk_secure test to verify this behavior. PR: bin/126849
Diffstat (limited to 'lib/libarchive/archive_write_disk.c')
-rw-r--r--lib/libarchive/archive_write_disk.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c
index b7313bc..b63a7b7 100644
--- a/lib/libarchive/archive_write_disk.c
+++ b/lib/libarchive/archive_write_disk.c
@@ -907,14 +907,26 @@ restore_entry(struct archive_write_disk *a)
* We know something is in the way, but we don't know what;
* we need to find out before we go any further.
*/
- if (lstat(a->name, &a->st) != 0) {
+ int r = 0;
+ /*
+ * The SECURE_SYMLINK logic has already removed a
+ * symlink to a dir if the client wants that. So
+ * follow the symlink if we're creating a dir.
+ */
+ if (S_ISDIR(a->mode))
+ r = stat(a->name, &a->st);
+ /*
+ * If it's not a dir (or it's a broken symlink),
+ * then don't follow it.
+ */
+ if (r != 0 || !S_ISDIR(a->mode))
+ r = lstat(a->name, &a->st);
+ if (r != 0) {
archive_set_error(&a->archive, errno,
"Can't stat existing object");
return (ARCHIVE_WARN);
}
- /* TODO: if it's a symlink... */
-
/*
* NO_OVERWRITE_NEWER doesn't apply to directories.
*/
OpenPOWER on IntegriCloud