enum timestamp_set_resolution ts_res;
char *connectpath;
char *origpath;
- struct smb_filename *cwd_fname; /* Working directory. */
+ struct files_struct *cwd_fsp; /* Working directory. */
bool tcon_done;
struct vfs_handle_struct *vfs_handles; /* for the new plugins */
} else if ((len >= 2) && (path[0] == '.') && (path[1] == '/')) {
if (len == 2) {
r = asprintf(&result, "%s",
- handle->conn->cwd_fname->base_name);
+ handle->conn->cwd_fsp->fsp_name->base_name);
} else {
r = asprintf(&result, "%s/%s",
- handle->conn->cwd_fname->base_name, &path[2]);
+ handle->conn->cwd_fsp->fsp_name->base_name, &path[2]);
}
} else {
r = asprintf(&result, "%s/%s",
- handle->conn->cwd_fname->base_name, path);
+ handle->conn->cwd_fsp->fsp_name->base_name, path);
}
if (r < 0) {
if (!ISDOT(smb_fname->base_name)) {
abs_name = talloc_asprintf(do_log_ctx(),
"%s/%s",
- conn->cwd_fname->base_name,
+ conn->cwd_fsp->fsp_name->base_name,
smb_fname->base_name);
} else {
abs_name = talloc_strdup(do_log_ctx(),
- conn->cwd_fname->base_name);
+ conn->cwd_fsp->fsp_name->base_name);
}
if (abs_name == NULL) {
return "";
const char *path = smb_fname->base_name;
char *dpath;
- if (!handle->conn->cwd_fname->base_name || !path) goto exit_rmdir;
+ if (!handle->conn->cwd_fsp->fsp_name->base_name || !path) goto exit_rmdir;
/* due to there is no way to change bDeleteVetoFiles variable
* from this module, gotta use talloc stuff..
goto exit_rmdir;
if (!(dpath = talloc_asprintf(ctx, "%s/%s%s",
- handle->conn->cwd_fname->base_name, path, add ? "/"APPLEDOUBLE : "")))
+ handle->conn->cwd_fsp->fsp_name->base_name, path, add ? "/"APPLEDOUBLE : "")))
goto exit_rmdir;
atalk_rrmdir(ctx, dpath);
return ret;
}
- if (atalk_build_paths(talloc_tos(), handle->conn->cwd_fname->base_name, oldname,
+ if (atalk_build_paths(talloc_tos(), handle->conn->cwd_fsp->fsp_name->base_name, oldname,
&adbl_path, &orig_path, &adbl_info,
&orig_info) != 0)
goto exit_rename;
}
if (atalk_build_paths(talloc_tos(),
- handle->conn->cwd_fname->base_name, path,
+ handle->conn->cwd_fsp->fsp_name->base_name, path,
&adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
goto exit_unlink;
return ret;
ret1 = atalk_build_paths(ctx,
- handle->conn->cwd_fname->base_name,
+ handle->conn->cwd_fsp->fsp_name->base_name,
smb_fname->base_name,
&adbl_path,
&orig_path,
if (!(ctx = talloc_init("chown_file")))
return ret;
- if (atalk_build_paths(ctx, handle->conn->cwd_fname->base_name,
+ if (atalk_build_paths(ctx, handle->conn->cwd_fsp->fsp_name->base_name,
smb_fname->base_name,
&adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
if (!(ctx = talloc_init("lchown_file")))
return ret;
- if (atalk_build_paths(ctx, handle->conn->cwd_fname->base_name,
+ if (atalk_build_paths(ctx, handle->conn->cwd_fsp->fsp_name->base_name,
smb_fname->base_name,
&adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
TALLOC_FREE(state->template_fname);
state->template_fname = talloc_asprintf(
state, "%s/%s",
- fsp->conn->cwd_fname->base_name, smb_fname->base_name);
+ fsp->conn->cwd_fsp->fsp_name->base_name, smb_fname->base_name);
if (state->template_fname == NULL) {
return res;
{
TALLOC_CTX *frame = talloc_stackframe();
connection_struct *conn = handle->conn;
- char *cwd_fname = fsp->conn->cwd_fname->base_name;
+ char *cwd_fname = fsp->conn->cwd_fsp->fsp_name->base_name;
char *fname = fsp->fsp_name->base_name;
const struct smb_filename *smb_fname = fsp->fsp_name;
struct smb_filename *q_smb_fname = NULL;
{
TALLOC_CTX *frame = talloc_stackframe();
connection_struct *conn = handle->conn;
- char *cwd_fname = fsp->conn->cwd_fname->base_name;
+ char *cwd_fname = fsp->conn->cwd_fsp->fsp_name->base_name;
char *fname = fsp->fsp_name->base_name;
const struct smb_filename *smb_fname = fsp->fsp_name;
struct smb_filename *q_smb_fname = NULL;
unbecome_root();
if (ret == -1) {
DBG_ERR("Delete [%s/%s] failed: %s\n",
- fsp->conn->cwd_fname->base_name,
+ fsp->conn->cwd_fsp->fsp_name->base_name,
fsp->fsp_name->base_name,
strerror(saved_errno));
errno = saved_errno;
bool is_cache)
{
connection_struct *conn = handle->conn;
- char *cwd_fname = fsp->conn->cwd_fname->base_name;
+ char *cwd_fname = fsp->conn->cwd_fsp->fsp_name->base_name;
char *fname = fsp->fsp_name->base_name;
TALLOC_CTX *mem_ctx = talloc_tos();
int i;
bool is_cache)
{
connection_struct *conn = handle->conn;
- const char *cwd_fname = fsp->conn->cwd_fname->base_name;
+ const char *cwd_fname = fsp->conn->cwd_fsp->fsp_name->base_name;
const char *fname = fsp->fsp_name->base_name;
TALLOC_CTX *mem_ctx = talloc_tos();
char *env_list = NULL;
virusfilter_result scan_result;
char *scan_report = NULL;
const char *fname = fsp->fsp_name->base_name;
- const char *cwd_fname = fsp->conn->cwd_fname->base_name;
+ const char *cwd_fname = fsp->conn->cwd_fsp->fsp_name->base_name;
struct virusfilter_cache_entry *scan_cache_e = NULL;
bool is_cache = false;
virusfilter_action file_action = VIRUSFILTER_ACTION_DO_NOTHING;
{
TALLOC_CTX *mem_ctx = talloc_tos();
struct virusfilter_config *config;
- const char *cwd_fname = fsp->conn->cwd_fname->base_name;
+ const char *cwd_fname = fsp->conn->cwd_fsp->fsp_name->base_name;
virusfilter_result scan_result;
const char *fname = fsp->fsp_name->base_name;
char *dir_name = NULL;
int ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
struct virusfilter_config *config = NULL;
char *fname = NULL;
- char *cwd_fname = handle->conn->cwd_fname->base_name;
+ char *cwd_fname = handle->conn->cwd_fsp->fsp_name->base_name;
if (ret != 0 && errno != ENOENT) {
return ret;
struct virusfilter_config *config = NULL;
char *fname = NULL;
char *dst_fname = NULL;
- char *cwd_fname = handle->conn->cwd_fname->base_name;
+ char *cwd_fname = handle->conn->cwd_fsp->fsp_name->base_name;
if (ret != 0) {
return ret;
const struct files_struct *fsp,
char **reportp)
{
- char *cwd_fname = fsp->conn->cwd_fname->base_name;
+ char *cwd_fname = fsp->conn->cwd_fsp->fsp_name->base_name;
const char *fname = fsp->fsp_name->base_name;
size_t filepath_len = strlen(cwd_fname) + 1 /* slash */ + strlen(fname);
struct virusfilter_io_handle *io_h = config->io_h;
const struct files_struct *fsp,
char **reportp)
{
- char *cwd_fname = fsp->conn->cwd_fname->base_name;
+ char *cwd_fname = fsp->conn->cwd_fsp->fsp_name->base_name;
const char *fname = fsp->fsp_name->base_name;
struct virusfilter_io_handle *io_h = config->io_h;
virusfilter_result result = VIRUSFILTER_RESULT_CLEAN;
const struct files_struct *fsp,
char **reportp)
{
- char *cwd_fname = fsp->conn->cwd_fname->base_name;
+ char *cwd_fname = fsp->conn->cwd_fsp->fsp_name->base_name;
const char *fname = fsp->fsp_name->base_name;
char fileurl[VIRUSFILTER_IO_URL_MAX+1];
int fileurl_len, fileurl_len2;
virusfilter_env_set(mem_ctx, env_list, "VIRUSFILTER_SERVICE_NAME",
lp_const_servicename(snum));
virusfilter_env_set(mem_ctx, env_list, "VIRUSFILTER_SERVICE_PATH",
- conn->cwd_fname->base_name);
+ conn->cwd_fsp->fsp_name->base_name);
client_addr_p = tsocket_address_inet_addr_string(
conn->sconn->remote_address, talloc_tos());
TALLOC_FREE(conn);
return NULL;
}
+ conn->cwd_fsp = talloc_zero(conn, struct files_struct);
+ if (conn->cwd_fsp == NULL) {
+ DBG_ERR("talloc_zero failed\n");
+ TALLOC_FREE(conn);
+ return NULL;
+ }
+ conn->cwd_fsp->fh = talloc_zero(conn->cwd_fsp, struct fd_handle);
+ if (conn->cwd_fsp->fh == NULL) {
+ DBG_ERR("talloc_zero failed\n");
+ TALLOC_FREE(conn);
+ return NULL;
+ }
conn->sconn = sconn;
conn->force_group_gid = (gid_t)-1;
+ conn->cwd_fsp->fh->fd = -1;
+ conn->cwd_fsp->fnum = FNUM_FIELD_INVALID;
+ conn->cwd_fsp->conn = conn;
DLIST_ADD(sconn->connections, conn);
sconn->num_connections++;
talloc_free(conn->connectpath);
conn->connectpath = destname;
/*
- * Ensure conn->cwd_fname is initialized.
+ * Ensure conn->cwd_fsp->fsp_name is initialized.
* start as conn->connectpath.
*/
- TALLOC_FREE(conn->cwd_fname);
- conn->cwd_fname = synthetic_smb_fname(conn,
+ TALLOC_FREE(conn->cwd_fsp->fsp_name);
+ conn->cwd_fsp->fsp_name = synthetic_smb_fname(conn,
conn->connectpath,
NULL,
NULL,
0);
- if (conn->cwd_fname == NULL) {
+ if (conn->cwd_fsp->fsp_name == NULL) {
return false;
}
return true;
if (current_user.done_chdir && ctx_p->need_chdir) {
int ret;
- ret = vfs_ChDir(ctx_p->conn, ctx_p->conn->cwd_fname);
+ ret = vfs_ChDir(ctx_p->conn, ctx_p->conn->cwd_fsp->fsp_name);
if (ret != 0) {
DBG_ERR("vfs_ChDir() failed!\n");
smb_panic("vfs_ChDir() failed!\n");
int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
{
int ret;
- struct smb_filename *old_cwd = conn->cwd_fname;
+ struct smb_filename *cwd = NULL;
if (!LastDir) {
LastDir = SMB_STRDUP("");
}
/*
- * Always replace conn->cwd_fname. We
+ * Always replace conn->cwd_fsp. We
* don't know if it's been modified by
* VFS modules in the stack.
*/
/* conn cache. */
- conn->cwd_fname = vfs_GetWd(conn, conn);
- if (conn->cwd_fname == NULL) {
+ cwd = vfs_GetWd(conn, conn);
+ if (cwd == NULL) {
/*
* vfs_GetWd() failed.
* We must be able to read cwd.
*/
int saved_errno = errno;
- if (old_cwd == NULL) {
+ if (conn->cwd_fsp->fsp_name == NULL) {
/*
* Failed on the very first chdir()+getwd()
* for this connection. We can't
/* NOTREACHED */
return -1;
}
- /* Restore original conn->cwd_fname. */
- conn->cwd_fname = old_cwd;
/* Return to the previous $cwd. */
- ret = SMB_VFS_CHDIR(conn, conn->cwd_fname);
+ ret = SMB_VFS_CHDIR(conn, conn->cwd_fsp->fsp_name);
if (ret != 0) {
smb_panic("conn->cwd getwd failed\n");
/* NOTREACHED */
SAFE_FREE(LastDir);
LastDir = SMB_STRDUP(smb_fname->base_name);
- DEBUG(4,("vfs_ChDir got %s\n", conn->cwd_fname->base_name));
+ /*
+ * (Indirect) Callers of vfs_ChDir() may still hold references to the
+ * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
+ * callers can use it for the lifetime of the SMB request.
+ */
+ talloc_move(talloc_tos(), &conn->cwd_fsp->fsp_name);
+
+ conn->cwd_fsp->fsp_name = talloc_move(conn->cwd_fsp, &cwd);
+ conn->cwd_fsp->fh->fd = AT_FDCWD;
+
+ DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn->cwd_fsp));
- TALLOC_FREE(old_cwd);
return ret;
}