return -1;
}
-static char *skel_getwd(vfs_handle_struct *handle)
+static struct smb_filename *skel_getwd(vfs_handle_struct *handle,
+ TALLOC_CTX *ctx)
{
errno = ENOSYS;
return NULL;
return SMB_VFS_NEXT_CHDIR(handle, smb_fname);
}
-static char *skel_getwd(vfs_handle_struct *handle)
+static struct smb_filename *skel_getwd(vfs_handle_struct *handle,
+ TALLOC_CTX *ctx)
{
- return SMB_VFS_NEXT_GETWD(handle);
+ return SMB_VFS_NEXT_GETWD(handle, ctx);
}
static int skel_ntimes(vfs_handle_struct *handle,
case PDB_GETPWSID_CACHE:
case SINGLETON_CACHE_TALLOC:
case SHARE_MODE_LOCK_CACHE:
+ case GETWD_CACHE:
result = true;
break;
default:
to const struct smb_filename * */
/* Version 37 - Change chdir from const char *
to const struct smb_filename * */
+/* Version 37 - Change getwd from char *
+ to const struct smb_filename * */
+/* Version 37 - Change conn->cwd from char *
+ to struct smb_filename * */
#define SMB_VFS_INTERFACE_VERSION 37
enum timestamp_set_resolution ts_res;
char *connectpath;
char *origpath;
- char *cwd; /* Working directory. */
+ struct smb_filename *cwd_fname; /* Working directory. */
struct vfs_handle_struct *vfs_handles; /* for the new plugins */
gid_t gid);
int (*chdir_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname);
- char *(*getwd_fn)(struct vfs_handle_struct *handle);
+ struct smb_filename *(*getwd_fn)(struct vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx);
int (*ntimes_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
struct smb_file_time *ft);
gid_t gid);
int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname);
-char *smb_vfs_call_getwd(struct vfs_handle_struct *handle);
+struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
+ TALLOC_CTX *ctx);
int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
struct smb_file_time *ft);
#define SMB_VFS_NEXT_CHDIR(handle, smb_fname) \
smb_vfs_call_chdir((handle)->next, (smb_fname))
-#define SMB_VFS_GETWD(conn) \
- smb_vfs_call_getwd((conn)->vfs_handles)
-#define SMB_VFS_NEXT_GETWD(handle) \
- smb_vfs_call_getwd((handle)->next)
+#define SMB_VFS_GETWD(conn, ctx) \
+ smb_vfs_call_getwd((conn)->vfs_handles, (ctx))
+#define SMB_VFS_NEXT_GETWD(handle, ctx) \
+ smb_vfs_call_getwd((handle)->next, (ctx))
#define SMB_VFS_NTIMES(conn, path, ts) \
smb_vfs_call_ntimes((conn)->vfs_handles, (path), (ts))
struct smb_filename local_fname = {0};
struct smb_filename parent_dir_fname = {0};
int saved_errno = 0;
- char *saved_dir = NULL;
- struct smb_filename saved_dir_fname = {0};
+ struct smb_filename *saved_dir_fname = NULL;
- saved_dir = vfs_GetWd(talloc_tos(),conn);
- if (!saved_dir) {
+ saved_dir_fname = vfs_GetWd(talloc_tos(),conn);
+ if (saved_dir_fname == NULL) {
saved_errno = errno;
goto out;
}
- saved_dir_fname = (struct smb_filename) { .base_name = saved_dir };
if (!parent_dirname(talloc_tos(), smb_fname->base_name,
&parent_dir, &final_component)) {
TALLOC_FREE(parent_dir);
- if (saved_dir) {
- vfs_ChDir(conn, &saved_dir_fname);
+ if (saved_dir_fname) {
+ vfs_ChDir(conn, saved_dir_fname);
+ TALLOC_FREE(saved_dir_fname);
}
if (saved_errno) {
errno = saved_errno;
WRAP_RETURN(result);
}
-static char *cephwrap_getwd(struct vfs_handle_struct *handle)
+static struct smb_filename *cephwrap_getwd(struct vfs_handle_struct *handle,
+ TALLOC_CTX *ctx)
{
const char *cwd = ceph_getcwd(handle->data);
DBG_DEBUG("[CEPH] getwd(%p) = %s\n", handle, cwd);
- return SMB_STRDUP(cwd);
+ return synthetic_smb_fname(ctx,
+ cwd,
+ NULL,
+ NULL,
+ 0);
}
static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, files_struct *fsp, off_t len)
return result;
}
-static char *vfswrap_getwd(vfs_handle_struct *handle)
+static struct smb_filename *vfswrap_getwd(vfs_handle_struct *handle,
+ TALLOC_CTX *ctx)
{
char *result;
+ struct smb_filename *smb_fname = NULL;
START_PROFILE(syscall_getwd);
result = sys_getwd();
END_PROFILE(syscall_getwd);
- return result;
+ smb_fname = synthetic_smb_fname(ctx,
+ result,
+ NULL,
+ NULL,
+ 0);
+ if (smb_fname == NULL) {
+ SAFE_FREE(result);
+ }
+ return smb_fname;
}
/*********************************************************************
}
if (ISDOT(data->smb_fname->base_name)) {
- data->smb_fname->base_name = vfs_GetWd(data, handle->conn);
+ struct smb_filename *cwd_fname = vfs_GetWd(data, handle->conn);
+ if (cwd_fname == NULL) {
+ TALLOC_FREE(data);
+ return NULL;
+ }
+ TALLOC_FREE(data->smb_fname->base_name);
+ data->smb_fname->base_name = talloc_move(data->smb_fname,
+ &cwd_fname->base_name);
+ TALLOC_FREE(cwd_fname);
}
/* Open the underlying directory and count the number of entries */
return result;
}
-static char *smb_full_audit_getwd(vfs_handle_struct *handle)
+static struct smb_filename *smb_full_audit_getwd(vfs_handle_struct *handle,
+ TALLOC_CTX *ctx)
{
- char *result;
+ struct smb_filename *result;
- result = SMB_VFS_NEXT_GETWD(handle);
+ result = SMB_VFS_NEXT_GETWD(handle, ctx);
do_log(SMB_VFS_OP_GETWD, (result != NULL), handle, "%s",
- result == NULL? "" : result);
+ result == NULL? "" : result->base_name);
return result;
}
return glfs_chdir(handle->data, smb_fname->base_name);
}
-static char *vfs_gluster_getwd(struct vfs_handle_struct *handle)
+static struct smb_filename *vfs_gluster_getwd(struct vfs_handle_struct *handle,
+ TALLOC_CTX *ctx)
{
char *cwd;
char *ret;
+ struct smb_filename *smb_fname = NULL;
cwd = SMB_CALLOC_ARRAY(char, PATH_MAX);
if (cwd == NULL) {
if (ret == 0) {
free(cwd);
}
- return ret;
+ smb_fname = synthetic_smb_fname(ctx,
+ ret,
+ NULL,
+ NULL,
+ 0);
+ free(cwd);
+ return smb_fname;
}
static int vfs_gluster_ntimes(struct vfs_handle_struct *handle,
const char *path = smb_fname->base_name;
char *dpath;
- if (!handle->conn->cwd || !path) goto exit_rmdir;
+ if (!handle->conn->cwd_fname->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, path, add ? "/"APPLEDOUBLE : "")))
+ handle->conn->cwd_fname->base_name, path, add ? "/"APPLEDOUBLE : "")))
goto exit_rmdir;
atalk_rrmdir(ctx, dpath);
return ret;
}
- if (atalk_build_paths(talloc_tos(), handle->conn->cwd, oldname,
+ if (atalk_build_paths(talloc_tos(), handle->conn->cwd_fname->base_name, oldname,
&adbl_path, &orig_path, &adbl_info,
&orig_info) != 0)
goto exit_rename;
}
}
- if (atalk_build_paths(talloc_tos(), handle->conn->cwd, path,
+ if (atalk_build_paths(talloc_tos(),
+ handle->conn->cwd_fname->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,
+ handle->conn->cwd_fname->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, smb_fname->base_name,
- &adbl_path, &orig_path,
- &adbl_info, &orig_info) != 0)
+ if (atalk_build_paths(ctx, handle->conn->cwd_fname->base_name,
+ smb_fname->base_name,
+ &adbl_path, &orig_path,
+ &adbl_info, &orig_info) != 0)
goto exit_chown;
if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) {
if (!(ctx = talloc_init("lchown_file")))
return ret;
- if (atalk_build_paths(ctx, handle->conn->cwd, smb_fname->base_name,
- &adbl_path, &orig_path,
- &adbl_info, &orig_info) != 0)
+ if (atalk_build_paths(ctx, handle->conn->cwd_fname->base_name,
+ smb_fname->base_name,
+ &adbl_path, &orig_path,
+ &adbl_info, &orig_info) != 0)
goto exit_lchown;
if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) {
TALLOC_FREE(state->template_fname);
state->template_fname = talloc_asprintf(
- state, "%s/%s", fsp->conn->cwd, smb_fname->base_name);
+ state, "%s/%s",
+ fsp->conn->cwd_fname->base_name, smb_fname->base_name);
if (state->template_fname == NULL) {
return res;
const char *connectpath)
{
struct shadow_copy2_private *priv = NULL;
- char *cwd = NULL;
+ struct smb_filename *cwd_fname = NULL;
SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private,
return);
TALLOC_FREE(priv->shadow_cwd);
- cwd = SMB_VFS_NEXT_GETWD(handle);
- if (cwd == NULL) {
+ cwd_fname = SMB_VFS_NEXT_GETWD(handle, talloc_tos());
+ if (cwd_fname == NULL) {
smb_panic("getwd failed\n");
}
- DBG_DEBUG("shadow cwd = %s\n", cwd);
- priv->shadow_cwd = talloc_strdup(priv, cwd);
- SAFE_FREE(cwd);
+ DBG_DEBUG("shadow cwd = %s\n", cwd_fname->base_name);
+ priv->shadow_cwd = talloc_strdup(priv, cwd_fname->base_name);
+ TALLOC_FREE(cwd_fname);
if (priv->shadow_cwd == NULL) {
smb_panic("talloc failed\n");
}
return result;
}
-static char *smb_time_audit_getwd(vfs_handle_struct *handle)
+static struct smb_filename *smb_time_audit_getwd(vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx)
{
- char *result;
+ struct smb_filename *result;
struct timespec ts1,ts2;
double timediff;
clock_gettime_mono(&ts1);
- result = SMB_VFS_NEXT_GETWD(handle);
+ result = SMB_VFS_NEXT_GETWD(handle, mem_ctx);
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
{
struct smb_Dir *dir_hnd = NULL;
struct smb_filename *smb_fname_cwd = NULL;
- struct smb_filename saved_dir_fname = {0};
- char *saved_dir = vfs_GetWd(talloc_tos(), conn);
+ struct smb_filename *saved_dir_fname = vfs_GetWd(talloc_tos(), conn);
struct privilege_paths *priv_paths = req->priv_paths;
int ret;
- if (saved_dir == NULL) {
+ if (saved_dir_fname == NULL) {
return NULL;
}
- saved_dir_fname = (struct smb_filename) { .base_name = saved_dir };
-
if (vfs_ChDir(conn, smb_dname) == -1) {
return NULL;
}
out:
- vfs_ChDir(conn, &saved_dir_fname);
- TALLOC_FREE(saved_dir);
+ vfs_ChDir(conn, saved_dir_fname);
+ TALLOC_FREE(saved_dir_fname);
return dir_hnd;
}
{
struct smb_Dir *dir_hnd = NULL;
struct smb_filename *smb_fname_cwd = NULL;
- struct smb_filename saved_dir_fname = {0};
- char *saved_dir = vfs_GetWd(ctx, conn);
+ struct smb_filename *saved_dir_fname = vfs_GetWd(ctx, conn);
NTSTATUS status;
- if (saved_dir == NULL) {
+ if (saved_dir_fname == NULL) {
return NULL;
}
- saved_dir_fname = (struct smb_filename) { .base_name = saved_dir };
-
if (vfs_ChDir(conn, smb_dname) == -1) {
goto out;
}
out:
- vfs_ChDir(conn, &saved_dir_fname);
- TALLOC_FREE(saved_dir);
+ vfs_ChDir(conn, saved_dir_fname);
+ TALLOC_FREE(saved_dir_fname);
return dir_hnd;
}
struct smb_filename **poldcwd_fname)
{
connection_struct *conn;
- char *oldcwd = NULL;
- struct smb_filename *smb_fname_oldcwd = NULL;
+ struct smb_filename *oldcwd_fname = NULL;
struct smb_filename smb_fname_connectpath = {0};
NTSTATUS status = create_conn_struct(ctx, ev,
* user we will fail.... WTF ? JRA.
*/
- oldcwd = vfs_GetWd(ctx, conn);
- if (oldcwd == NULL) {
+ oldcwd_fname = vfs_GetWd(ctx, conn);
+ if (oldcwd_fname == NULL) {
status = map_nt_error_from_unix(errno);
DEBUG(3, ("vfs_GetWd failed: %s\n", strerror(errno)));
conn_free(conn);
return status;
}
- smb_fname_oldcwd = synthetic_smb_fname(ctx,
- oldcwd,
- NULL,
- NULL,
- 0);
- if (smb_fname_oldcwd == NULL) {
- status = NT_STATUS_NO_MEMORY;
- conn_free(conn);
- return status;
- }
-
smb_fname_connectpath = (struct smb_filename) {
.base_name = conn->connectpath
};
DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. "
"Error was %s\n",
conn->connectpath, strerror(errno) ));
- TALLOC_FREE(smb_fname_oldcwd);
+ TALLOC_FREE(oldcwd_fname);
conn_free(conn);
return status;
}
*pconn = conn;
- *poldcwd_fname = smb_fname_oldcwd;
+ *poldcwd_fname = oldcwd_fname;
return NT_STATUS_OK;
}
int fd = -1;
char *link_target = NULL;
int link_len = -1;
- char *oldwd = NULL;
- struct smb_filename oldwd_fname = {0};
+ struct smb_filename *oldwd_fname = NULL;
size_t rootdir_len = 0;
char *resolved_name = NULL;
bool matched = false;
goto out;
}
- oldwd = vfs_GetWd(talloc_tos(), conn);
- if (oldwd == NULL) {
+ oldwd_fname = vfs_GetWd(talloc_tos(), conn);
+ if (oldwd_fname == NULL) {
goto out;
}
- oldwd_fname = (struct smb_filename) { .base_name = oldwd };
-
/* Ensure we operate from the root of the share. */
if (vfs_ChDir(conn, conn_rootdir_fname) == -1) {
goto out;
SAFE_FREE(resolved_name);
TALLOC_FREE(link_target);
- if (oldwd != NULL) {
- int ret = vfs_ChDir(conn, &oldwd_fname);
+ if (oldwd_fname != NULL) {
+ int ret = vfs_ChDir(conn, oldwd_fname);
if (ret == -1) {
smb_panic("unable to get back to old directory\n");
}
- TALLOC_FREE(oldwd);
+ TALLOC_FREE(oldwd_fname);
}
if (saved_errno != 0) {
errno = saved_errno;
int fd = -1;
struct smb_filename *smb_fname_rel = NULL;
int saved_errno = 0;
- char *oldwd = NULL;
- struct smb_filename oldwd_fname = {0};
+ struct smb_filename *oldwd_fname = NULL;
char *parent_dir = NULL;
struct smb_filename parent_dir_fname = {0};
const char *final_component = NULL;
parent_dir_fname = (struct smb_filename) { .base_name = parent_dir };
- oldwd = vfs_GetWd(talloc_tos(), conn);
- if (oldwd == NULL) {
+ oldwd_fname = vfs_GetWd(talloc_tos(), conn);
+ if (oldwd_fname == NULL) {
goto out;
}
- oldwd_fname = (struct smb_filename) { .base_name = oldwd };
-
/* Pin parent directory in place. */
if (vfs_ChDir(conn, &parent_dir_fname) == -1) {
goto out;
TALLOC_FREE(parent_dir);
TALLOC_FREE(smb_fname_rel);
- if (oldwd != NULL) {
- int ret = vfs_ChDir(conn, &oldwd_fname);
+ if (oldwd_fname != NULL) {
+ int ret = vfs_ChDir(conn, oldwd_fname);
if (ret == -1) {
smb_panic("unable to get back to old directory\n");
}
- TALLOC_FREE(oldwd);
+ TALLOC_FREE(oldwd_fname);
}
if (saved_errno != 0) {
errno = saved_errno;
{
struct smb_filename *smb_fname_parent;
struct smb_filename *smb_fname_cwd = NULL;
- char *saved_dir = NULL;
- struct smb_filename smb_fname_saved_dir = {0};
+ struct smb_filename *saved_dir_fname = NULL;
TALLOC_CTX *ctx = talloc_tos();
NTSTATUS status = NT_STATUS_OK;
int ret;
should work on any UNIX (thanks tridge :-). JRA.
*/
- saved_dir = vfs_GetWd(ctx,conn);
- if (!saved_dir) {
+ saved_dir_fname = vfs_GetWd(ctx,conn);
+ if (!saved_dir_fname) {
status = map_nt_error_from_unix(errno);
DEBUG(0,("change_dir_owner_to_parent: failed to get "
"current working directory. Error was %s\n",
goto out;
}
- smb_fname_saved_dir = (struct smb_filename) { .base_name = saved_dir };
-
/* Chdir into the new path. */
if (vfs_ChDir(conn, smb_dname) == -1) {
status = map_nt_error_from_unix(errno);
}
chdir:
- vfs_ChDir(conn, &smb_fname_saved_dir);
+ vfs_ChDir(conn, saved_dir_fname);
out:
- TALLOC_FREE(saved_dir);
+ TALLOC_FREE(saved_dir_fname);
TALLOC_FREE(smb_fname_parent);
TALLOC_FREE(smb_fname_cwd);
return status;
SMB_STRUCT_STAT *sbuf, char **talloced);
int vfs_ChDir(connection_struct *conn,
const struct smb_filename *smb_fname);
-char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn);
+struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn);
NTSTATUS check_reduced_name(connection_struct *conn,
const char *cwd_name,
const char *fname);
talloc_free(conn->connectpath);
conn->connectpath = destname;
- /* Ensure conn->cwd is initialized - start as conn->connectpath. */
- TALLOC_FREE(conn->cwd);
- conn->cwd = talloc_strdup(conn, conn->connectpath);
- if (!conn->cwd) {
+ /*
+ * Ensure conn->cwd_fname is initialized.
+ * start as conn->connectpath.
+ */
+ TALLOC_FREE(conn->cwd_fname);
+ conn->cwd_fname = synthetic_smb_fname(conn,
+ conn->connectpath,
+ NULL,
+ NULL,
+ 0);
+ if (conn->cwd_fname == NULL) {
return false;
}
return true;
LastDir = SMB_STRDUP(smb_fname->base_name);
/* conn cache. */
- TALLOC_FREE(conn->cwd);
- conn->cwd = vfs_GetWd(conn, conn);
- DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
+ TALLOC_FREE(conn->cwd_fname);
+ conn->cwd_fname = vfs_GetWd(conn, conn);
+ if (conn->cwd_fname == NULL) {
+ smb_panic("con->cwd getwd failed\n");
+ /* NOTREACHED */
+ return -1;
+ }
+ DEBUG(4,("vfs_ChDir got %s\n",conn->cwd_fname->base_name));
}
return ret;
}
format. Note this can be called with conn == NULL.
********************************************************************/
-char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
+struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
{
- char *current_dir = NULL;
- char *result = NULL;
- DATA_BLOB cache_value;
+ struct smb_filename *current_dir_fname = NULL;
struct file_id key;
struct smb_filename *smb_fname_dot = NULL;
struct smb_filename *smb_fname_full = NULL;
+ struct smb_filename *result = NULL;
if (!lp_getwd_cache()) {
goto nocache;
key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
- if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
- data_blob_const(&key, sizeof(key)),
- &cache_value)) {
- goto nocache;
- }
-
- SMB_ASSERT((cache_value.length > 0)
- && (cache_value.data[cache_value.length-1] == '\0'));
+ smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
+ smbd_memcache(),
+ GETWD_CACHE,
+ data_blob_const(&key, sizeof(key)));
- smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
- NULL, NULL, 0);
if (smb_fname_full == NULL) {
- errno = ENOMEM;
- goto out;
+ goto nocache;
}
if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
(S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
/*
* Ok, we're done
+ * Note: smb_fname_full is owned by smbd_memcache()
+ * so we must make a copy to return.
*/
- result = talloc_strdup(ctx, smb_fname_full->base_name);
+ result = cp_smb_filename(ctx, smb_fname_full);
if (result == NULL) {
errno = ENOMEM;
}
* systems, or the not quite so bad getwd.
*/
- current_dir = SMB_VFS_GETWD(conn);
- if (current_dir == NULL) {
+ current_dir_fname = SMB_VFS_GETWD(conn, ctx);
+ if (current_dir_fname == NULL) {
DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
strerror(errno)));
goto out;
if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
- memcache_add(smbd_memcache(), GETWD_CACHE,
- data_blob_const(&key, sizeof(key)),
- data_blob_const(current_dir,
- strlen(current_dir)+1));
- }
+ /*
+ * smbd_memcache() will own current_dir_fname after the
+ * memcache_add_talloc call, so we must make
+ * a copy on ctx to return.
+ */
+ result = cp_smb_filename(ctx, current_dir_fname);
+ if (result == NULL) {
+ errno = ENOMEM;
+ }
- result = talloc_strdup(ctx, current_dir);
- if (result == NULL) {
- errno = ENOMEM;
+ /*
+ * Ensure the memory going into the cache
+ * doesn't have a destructor so it can be
+ * cleanly freed.
+ */
+ talloc_set_destructor(current_dir_fname, NULL);
+
+ memcache_add_talloc(smbd_memcache(),
+ GETWD_CACHE,
+ data_blob_const(&key, sizeof(key)),
+ ¤t_dir_fname);
+ /* current_dir_fname is now == NULL here. */
+ } else {
+ /* current_dir_fname is already allocated on ctx. */
+ result = current_dir_fname;
}
out:
TALLOC_FREE(smb_fname_dot);
- TALLOC_FREE(smb_fname_full);
- SAFE_FREE(current_dir);
+ /*
+ * Don't free current_dir_fname here. It's either been moved
+ * to the memcache or is being returned in result.
+ */
return result;
}
char *dir_name = NULL;
const char *last_component = NULL;
char *resolved_name = NULL;
- char *saved_dir = NULL;
struct smb_filename *saved_dir_fname = NULL;
struct smb_filename *smb_fname_cwd = NULL;
struct privilege_paths *priv_paths = NULL;
goto err;
}
/* Remember where we were. */
- saved_dir = vfs_GetWd(ctx, conn);
- if (!saved_dir) {
+ saved_dir_fname = vfs_GetWd(ctx, conn);
+ if (!saved_dir_fname) {
status = map_nt_error_from_unix(errno);
goto err;
}
- saved_dir_fname = synthetic_smb_fname(ctx,
- saved_dir,
- NULL,
- NULL,
- 0);
- if (saved_dir_fname == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto err;
- }
-
- /* Go to the parent directory to lock in memory. */
if (vfs_ChDir(conn, &priv_paths->parent_name) == -1) {
status = map_nt_error_from_unix(errno);
goto err;
err:
- if (saved_dir_fname) {
+ if (saved_dir_fname != NULL) {
vfs_ChDir(conn, saved_dir_fname);
- TALLOC_FREE(saved_dir);
TALLOC_FREE(saved_dir_fname);
}
SAFE_FREE(resolved_name);
* and always act using lchown to ensure we
* don't deref any symbolic links.
*/
- char *saved_dir = NULL;
char *parent_dir = NULL;
const char *final_component = NULL;
struct smb_filename *local_smb_fname = NULL;
struct smb_filename parent_dir_fname = {0};
- struct smb_filename saved_dir_fname = {0};
+ struct smb_filename *saved_dir_fname = NULL;
- saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
- if (!saved_dir) {
+ saved_dir_fname = vfs_GetWd(talloc_tos(),fsp->conn);
+ if (!saved_dir_fname) {
status = map_nt_error_from_unix(errno);
DEBUG(0,("vfs_chown_fsp: failed to get "
"current working directory. Error was %s\n",
return status;
}
- saved_dir_fname = (struct smb_filename) {
- .base_name = saved_dir
- };
-
if (!parent_dirname(talloc_tos(),
fsp->fsp_name->base_name,
&parent_dir,
out:
- vfs_ChDir(fsp->conn, &saved_dir_fname);
+ vfs_ChDir(fsp->conn, saved_dir_fname);
TALLOC_FREE(local_smb_fname);
- TALLOC_FREE(saved_dir);
+ TALLOC_FREE(saved_dir_fname);
TALLOC_FREE(parent_dir);
return status;
return handle->fns->chdir_fn(handle, smb_fname);
}
-char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
+struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
+ TALLOC_CTX *ctx)
{
VFS_FIND(getwd);
- return handle->fns->getwd_fn(handle);
+ return handle->fns->getwd_fn(handle, ctx);
}
int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
- char *buf = SMB_VFS_GETWD(vfs->conn);
- if (buf == NULL) {
+ struct smb_filename *smb_fname = SMB_VFS_GETWD(vfs->conn, talloc_tos());
+ if (smb_fname == NULL) {
printf("getwd: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
- printf("getwd: %s\n", buf);
- SAFE_FREE(buf);
+ printf("getwd: %s\n", smb_fname->base_name);
+ TALLOC_FREE(smb_fname);
return NT_STATUS_OK;
}
static bool run_local_memcache(int dummy)
{
struct memcache *cache;
- DATA_BLOB k1, k2;
- DATA_BLOB d1, d2, d3;
- DATA_BLOB v1, v2, v3;
+ DATA_BLOB k1, k2, k3;
+ DATA_BLOB d1, d3;
+ DATA_BLOB v1, v3;
TALLOC_CTX *mem_ctx;
+ char *ptr1 = NULL;
+ char *ptr2 = NULL;
+
char *str1, *str2;
size_t size1, size2;
bool ret = false;
+ mem_ctx = talloc_init("foo");
+ if (mem_ctx == NULL) {
+ return false;
+ }
+
+ /* STAT_CACHE TESTS */
+
cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
if (cache == NULL) {
}
d1 = data_blob_const("d1", 2);
- d2 = data_blob_const("d2", 2);
d3 = data_blob_const("d3", 2);
k1 = data_blob_const("d1", 2);
k2 = data_blob_const("d2", 2);
+ k3 = data_blob_const("d3", 2);
memcache_add(cache, STAT_CACHE, k1, d1);
- memcache_add(cache, GETWD_CACHE, k2, d2);
if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
printf("could not find k1\n");
return false;
}
- if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
- printf("could not find k2\n");
+ memcache_add(cache, STAT_CACHE, k1, d3);
+
+ if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
+ printf("could not find replaced k1\n");
return false;
}
- if (!data_blob_equal(d2, v2)) {
+ if (!data_blob_equal(d3, v3)) {
return false;
}
- memcache_add(cache, STAT_CACHE, k1, d3);
+ TALLOC_FREE(cache);
- if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
- printf("could not find replaced k1\n");
+ /* GETWD_CACHE TESTS */
+ str1 = talloc_strdup(mem_ctx, "string1");
+ if (str1 == NULL) {
return false;
}
- if (!data_blob_equal(d3, v3)) {
+ ptr2 = str1; /* Keep an alias for comparison. */
+
+ str2 = talloc_strdup(mem_ctx, "string2");
+ if (str2 == NULL) {
+ return false;
+ }
+
+ cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
+ if (cache == NULL) {
+ printf("memcache_init failed\n");
+ return false;
+ }
+
+ memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
+ /* str1 == NULL now. */
+ ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
+ if (ptr1 == NULL) {
+ printf("could not find k2\n");
+ return false;
+ }
+ if (ptr1 != ptr2) {
+ printf("fetch of k2 got wrong string\n");
return false;
}
- memcache_add(cache, GETWD_CACHE, k1, d1);
+ /* Add a blob to ensure k2 gets purged. */
+ d3 = data_blob_talloc_zero(mem_ctx, 180);
+ memcache_add(cache, STAT_CACHE, k3, d3);
- if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
+ ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
+ if (ptr2 != NULL) {
printf("Did find k2, should have been purged\n");
return false;
}
TALLOC_FREE(cache);
-
- cache = memcache_init(NULL, 0);
+ TALLOC_FREE(mem_ctx);
mem_ctx = talloc_init("foo");
+ if (mem_ctx == NULL) {
+ return false;
+ }
+
+ cache = memcache_init(NULL, 0);
+ if (cache == NULL) {
+ return false;
+ }
str1 = talloc_strdup(mem_ctx, "string1");
+ if (str1 == NULL) {
+ return false;
+ }
str2 = talloc_strdup(mem_ctx, "string2");
-
+ if (str2 == NULL) {
+ return false;
+ }
memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
data_blob_string_const("torture"), &str1);
size1 = talloc_total_size(cache);