aboutsummaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2006-05-05 05:55:40 +0000
committerWayne Davison <wayned@samba.org>2006-05-05 05:55:40 +0000
commitf47807900b528fc89dfb0d331f98be627ff67429 (patch)
treebb41ef5207a812187403c76918a4d1d9384c4045 /util.c
parent40410a38bc1d563463fbaa08e38b25ad974d3db7 (diff)
downloadandroid_external_rsync-f47807900b528fc89dfb0d331f98be627ff67429.tar.gz
android_external_rsync-f47807900b528fc89dfb0d331f98be627ff67429.tar.bz2
android_external_rsync-f47807900b528fc89dfb0d331f98be627ff67429.zip
Added a new function named die_on_unsafe_path(). This is used
by a non-chroot daemon to ensure that a user-supplied path does not contain an unsafe symlink element.
Diffstat (limited to 'util.c')
-rw-r--r--util.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/util.c b/util.c
index 875af11e..337aa83f 100644
--- a/util.c
+++ b/util.c
@@ -900,6 +900,46 @@ int safe_stat(const char *fname, STRUCT_STAT *stp)
#endif
}
+void die_on_unsafe_path(char *path, int strip_filename)
+{
+#ifdef SUPPORT_LINKS
+ char *final_slash, *p;
+ STRUCT_STAT st;
+
+ if (!path)
+ return;
+ if (strip_filename) {
+ if (!(final_slash = strrchr(path, '/')))
+ return;
+ *final_slash = '\0';
+ } else
+ final_slash = NULL;
+
+ p = path;
+ if (*p == '/')
+ p += module_dirlen + 1;
+ while (*p) {
+ if ((p = strchr(p, '/')) != NULL)
+ *p = '\0';
+ if (safe_stat(path, &st) < 0) {
+ *p++ = '/';
+ goto done;
+ }
+ if (S_ISLNK(st.st_mode)) {
+ rprintf(FERROR, "Unsafe path: %s\n", path);
+ exit_cleanup(RERR_SYNTAX);
+ }
+ if (!p)
+ break;
+ *p++ = '/';
+ }
+
+ done:
+ if (final_slash)
+ *final_slash = '/';
+#endif
+}
+
/* Like chdir(), but it keeps track of the current directory (in the
* global "curr_dir"), and ensures that the path size doesn't overflow.
* Also cleans the path using the clean_fname() function. */