void print_child_argv(char **cmd)
{
- rprintf(FINFO, "opening connection using ");
+ rprintf(FCLIENT, "opening connection using ");
for (; *cmd; cmd++) {
/* Look for characters that ought to be quoted. This
* is not a great quoting algorithm, but it's
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789"
",.-_=+@/") != strlen(*cmd)) {
- rprintf(FINFO, "\"%s\" ", *cmd);
+ rprintf(FCLIENT, "\"%s\" ", *cmd);
} else {
- rprintf(FINFO, "%s ", *cmd);
+ rprintf(FCLIENT, "%s ", *cmd);
}
}
- rprintf(FINFO, "\n");
+ rprintf(FCLIENT, "\n");
}
void out_of_memory(char *str)
{
- rprintf(FERROR, "ERROR: out of memory in %s\n", str);
+ rprintf(FERROR, "ERROR: out of memory in %s [%s]\n", str, who_am_i());
exit_cleanup(RERR_MALLOC);
}
void overflow_exit(char *str)
{
- rprintf(FERROR, "ERROR: buffer overflow in %s\n", str);
+ rprintf(FERROR, "ERROR: buffer overflow in %s [%s]\n", str, who_am_i());
exit_cleanup(RERR_MALLOC);
}
if ((p = strchr(p, '/')) != NULL)
*p = '\0';
if (safe_stat(path, &st) < 0) {
- *p++ = '/';
+ if (p)
+ *p = '/';
goto done;
}
if (S_ISLNK(st.st_mode)) {
/* 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. */
-int push_dir(char *dir)
+int push_dir(char *dir, int set_path_only)
{
static int initialised;
unsigned int len;
if ((*dir == '/' ? len : curr_dir_len + 1 + len) >= sizeof curr_dir)
return 0;
- if (chdir(dir))
+ if (!set_path_only && chdir(dir))
return 0;
if (*dir == '/') {
if (*fn == '/')
p1 = p2 = "";
else {
- p1 = curr_dir;
+ p1 = curr_dir + module_dirlen;
for (p2 = p1; *p2 == '/'; p2++) {}
if (*p2)
p2 = "/";
m1 = " (in ";
m2 = lp_name(module_id);
m3 = ")";
- if (p1 == curr_dir) {
- if (!lp_use_chroot(module_id)) {
- char *p = lp_path(module_id);
- if (*p != '/' || p[1])
- p1 += strlen(p);
- }
- }
} else
m1 = m2 = m3 = "";
- asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3);
+ if (asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3) <= 0)
+ out_of_memory("full_fname");
return result;
}
if ((int)pathjoin(t, sz, partial_dir, fn) >= sz)
return NULL;
if (server_filter_list.head) {
- static int len;
- if (!len)
- len = strlen(partial_dir);
- t[len] = '\0';
+ t = strrchr(partial_fname, '/');
+ *t = '\0';
if (check_filter(&server_filter_list, partial_fname, 1) < 0)
return NULL;
- t[len] = '/';
+ *t = '/';
if (check_filter(&server_filter_list, partial_fname, 0) < 0)
return NULL;
}
if (create) {
STRUCT_STAT st;
int statret = do_lstat(dir, &st);
+ if (sanitize_paths && *partial_dir != '/')
+ die_on_unsafe_path(dir, 1); /* lstat handles last element */
if (statret == 0 && !S_ISDIR(st.st_mode)) {
if (do_unlink(dir) < 0)
return 0;