4
4
* Copyright (C) 1996-2000 Andrew Tridgell
5
5
* Copyright (C) 1996 Paul Mackerras
6
6
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
7
* Copyright (C) 2003-2008 Wayne Davison
7
* Copyright (C) 2003-2009 Wayne Davison
9
9
* This program is free software; you can redistribute it and/or modify
10
10
* it under the terms of the GNU General Public License as published by
1172
* Determine if a symlink points outside the current directory tree.
1171
/* Determine if a symlink points outside the current directory tree.
1173
1172
* This is considered "unsafe" because e.g. when mirroring somebody
1174
1173
* else's machine it might allow them to establish a symlink to
1175
1174
* /etc/passwd, and then read it through a web server.
1176
* Returns 1 if unsafe, 0 if safe.
1177
1178
* Null symlinks and absolute symlinks are always unsafe.
1179
1180
* Basically here we are concerned with symlinks whose target contains
1181
1182
* transferred directory. We are not allowed to go back up and
1184
* @param dest Target of the symlink in question.
1186
* @param src Top source directory currently applicable. Basically this
1187
* is the first parameter to rsync in a simple invocation, but it's
1188
* modified by flist.c in slightly complex ways.
1190
* @retval True if unsafe
1191
* @retval False is unsafe
1185
* "dest" is the target of the symlink in question.
1187
* "src" is the top source directory currently applicable at the level
1188
* of the referenced symlink. This is usually the symlink's full path
1189
* (including its name), as referenced from the root of the transfer. */
1195
1190
int unsafe_symlink(const char *dest, const char *src)
1197
1192
const char *name, *slash;
1204
1199
/* find out what our safety margin is */
1205
1200
for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
1206
if (strncmp(name, "../", 3) == 0) {
1208
} else if (strncmp(name, "./", 2) == 0) {
1201
/* ".." segment starts the count over. "." segment is ignored. */
1202
if (*name == '.' && (name[1] == '/' || (name[1] == '.' && name[2] == '/'))) {
1207
while (slash[1] == '/') slash++; /* just in case src isn't clean */
1214
if (strcmp(name, "..") == 0)
1209
if (*name == '.' && name[1] == '.' && name[2] == '\0')
1217
1212
for (name = dest; (slash = strchr(name, '/')) != 0; name = slash+1) {
1218
if (strncmp(name, "../", 3) == 0) {
1219
/* if at any point we go outside the current directory
1220
then stop - it is unsafe */
1223
} else if (strncmp(name, "./", 2) == 0) {
1213
if (*name == '.' && (name[1] == '/' || (name[1] == '.' && name[2] == '/'))) {
1214
if (name[1] == '.') {
1215
/* if at any point we go outside the current directory
1216
then stop - it is unsafe */
1222
while (slash[1] == '/') slash++;
1229
if (strcmp(name, "..") == 0)
1224
if (*name == '.' && name[1] == '.' && name[2] == '\0')
1235
1230
#define HUMANIFY(mult) \