return false;
}
-static int skel_symlink(vfs_handle_struct *handle, const char *oldpath,
- const char *newpath)
+static int skel_symlink(vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
errno = ENOSYS;
return -1;
return SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
}
-static int skel_symlink(vfs_handle_struct *handle, const char *oldpath,
- const char *newpath)
+static int skel_symlink(vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- return SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ return SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
}
static int skel_vfs_readlink(vfs_handle_struct *handle,
to const struct smb_filename * */
/* Version 37 - Change readlink from const char *
to const struct smb_filename * */
+/* Version 37 - Change symlink from const char *
+ to const struct smb_filename * */
#define SMB_VFS_INTERFACE_VERSION 37
uint32_t share_mode, uint32_t access_mask);
int (*linux_setlease_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, int leasetype);
bool (*getlock_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid);
- int (*symlink_fn)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath);
+ int (*symlink_fn)(struct vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname);
int (*readlink_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
char *buf,
bool smb_vfs_call_getlock(struct vfs_handle_struct *handle,
struct files_struct *fsp, off_t *poffset,
off_t *pcount, int *ptype, pid_t *ppid);
-int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
- const char *newpath);
+int smb_vfs_call_symlink(struct vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname);
int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
char *buf,
}
-static int cap_symlink(vfs_handle_struct *handle, const char *oldpath,
- const char *newpath)
+static int cap_symlink(vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- char *capold = capencode(talloc_tos(), oldpath);
- char *capnew = capencode(talloc_tos(), newpath);
+ char *capold = capencode(talloc_tos(), link_contents);
+ char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
+ struct smb_filename *new_cap_smb_fname = NULL;
+ int saved_errno = 0;
+ int ret;
if (!capold || !capnew) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew);
+ new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ capnew,
+ NULL,
+ NULL,
+ new_smb_fname->flags);
+ if (new_cap_smb_fname == NULL) {
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = SMB_VFS_NEXT_SYMLINK(handle,
+ capold,
+ new_cap_smb_fname);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ TALLOC_FREE(new_cap_smb_fname);
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+ return ret;
}
static int cap_readlink(vfs_handle_struct *handle,
return result;
}
-static int cephwrap_symlink(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int cephwrap_symlink(struct vfs_handle_struct *handle,
+ const char *link_target,
+ const struct smb_filename *new_smb_fname)
{
int result = -1;
- DBG_DEBUG("[CEPH] symlink(%p, %s, %s)\n", handle, oldpath, newpath);
- result = ceph_symlink(handle->data, oldpath, newpath);
+ DBG_DEBUG("[CEPH] symlink(%p, %s, %s)\n", handle,
+ link_target,
+ new_smb_fname->base_name);
+ result = ceph_symlink(handle->data,
+ link_target,
+ new_smb_fname->base_name);
DBG_DEBUG("[CEPH] symlink(...) = %d\n", result);
WRAP_RETURN(result);
}
return result;
}
-static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int vfswrap_symlink(vfs_handle_struct *handle,
+ const char *link_target,
+ const struct smb_filename *new_smb_fname)
{
int result;
START_PROFILE(syscall_symlink);
- result = symlink(oldpath, newpath);
+ result = symlink(link_target, new_smb_fname->base_name);
END_PROFILE(syscall_symlink);
return result;
}
}
static int smb_full_audit_symlink(vfs_handle_struct *handle,
- const char *oldpath, const char *newpath)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
int result;
- result = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ result = SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
do_log(SMB_VFS_OP_SYMLINK, (result >= 0), handle,
- "%s|%s", oldpath, newpath);
+ "%s|%s", link_contents, new_smb_fname->base_name);
return result;
}
}
static int vfs_gluster_symlink(struct vfs_handle_struct *handle,
- const char *oldpath, const char *newpath)
+ const char *link_target,
+ const struct smb_filename *new_smb_fname)
{
- return glfs_symlink(handle->data, oldpath, newpath);
+ return glfs_symlink(handle->data,
+ link_target,
+ new_smb_fname->base_name);
}
static int vfs_gluster_readlink(struct vfs_handle_struct *handle,
* Success: return 0
* Failure: set errno, return -1
*/
+
static int mh_symlink(vfs_handle_struct *handle,
- const char *oldpath,
- const char *newpath)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- int status;
- char *oldClientPath;
- char *newClientPath;
- TALLOC_CTX *ctx;
+ int status = -1;
+ char *client_link_contents = NULL;
+ struct smb_filename *newclientFname = NULL;
DEBUG(MH_INFO_DEBUG, ("Entering mh_symlink\n"));
- if (!is_in_media_files(oldpath) && !is_in_media_files(newpath))
- {
- status = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ if (!is_in_media_files(link_contents) &&
+ !is_in_media_files(new_smb_fname->base_name)) {
+ status = SMB_VFS_NEXT_SYMLINK(handle,
+ link_contents,
+ new_smb_fname);
goto out;
}
- oldClientPath = NULL;
- newClientPath = NULL;
- ctx = talloc_tos();
-
- if ((status = alloc_get_client_path(handle, ctx,
- oldpath,
- &oldClientPath)))
- {
+ if ((status = alloc_get_client_path(handle, talloc_tos(),
+ link_contents,
+ &client_link_contents))) {
goto err;
}
-
- if ((status = alloc_get_client_path(handle, ctx,
- newpath,
- &newClientPath)))
- {
+ if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
+ new_smb_fname,
+ &newclientFname))) {
goto err;
}
status = SMB_VFS_NEXT_SYMLINK(handle,
- oldClientPath,
- newClientPath);
-
+ client_link_contents,
+ newclientFname);
err:
- TALLOC_FREE(newClientPath);
- TALLOC_FREE(oldClientPath);
+ TALLOC_FREE(client_link_contents);
+ TALLOC_FREE(newclientFname);
out:
return status;
}
}
static int shadow_copy2_symlink(vfs_handle_struct *handle,
- const char *oldname, const char *newname)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
time_t timestamp_old = 0;
time_t timestamp_new = 0;
char *snappath_old = NULL;
char *snappath_new = NULL;
- if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname,
- ×tamp_old, NULL, &snappath_old)) {
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(),
+ handle,
+ link_contents,
+ ×tamp_old,
+ NULL,
+ &snappath_old)) {
return -1;
}
- if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname,
- ×tamp_new, NULL, &snappath_new)) {
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(),
+ handle,
+ new_smb_fname->base_name,
+ ×tamp_new,
+ NULL,
+ &snappath_new)) {
return -1;
}
if ((timestamp_old != 0) || (timestamp_new != 0)) {
errno = EROFS;
return -1;
}
- return SMB_VFS_NEXT_SYMLINK(handle, oldname, newname);
+ return SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
}
static int shadow_copy2_link(vfs_handle_struct *handle,
}
static int snapper_gmt_symlink(vfs_handle_struct *handle,
- const char *oldname, const char *newname)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- time_t timestamp_old, timestamp_new;
+ time_t timestamp_old = 0;
+ time_t timestamp_new = 0;
- if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, oldname,
- ×tamp_old, NULL)) {
+ if (!snapper_gmt_strip_snapshot(talloc_tos(),
+ handle,
+ link_contents,
+ ×tamp_old,
+ NULL)) {
return -1;
}
- if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, newname,
- ×tamp_new, NULL)) {
+ if (!snapper_gmt_strip_snapshot(talloc_tos(),
+ handle,
+ new_smb_fname->base_name,
+ ×tamp_new,
+ NULL)) {
return -1;
}
if ((timestamp_old != 0) || (timestamp_new != 0)) {
errno = EROFS;
return -1;
}
- return SMB_VFS_NEXT_SYMLINK(handle, oldname, newname);
+ return SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
}
static int snapper_gmt_link(vfs_handle_struct *handle,
talloc_free(tmp_ctx);
}
-/*
- sync two meta data changes for 1 names
- */
-static void syncops_name(const char *name)
-{
- char *parent;
- parent = parent_dir(NULL, name);
- if (parent) {
- syncops_sync_directory(parent);
- talloc_free(parent);
- }
-}
-
/*
sync two meta data changes for 1 names
*/
return ret;
}
-/* handle the rest with a macro */
-#define SYNCOPS_NEXT(op, fname, args) do { \
- int ret; \
- struct syncops_config_data *config; \
- SMB_VFS_HANDLE_GET_DATA(handle, config, \
- struct syncops_config_data, \
- return -1); \
- ret = SMB_VFS_NEXT_ ## op args; \
- if (ret == 0 \
- && config->onmeta && !config->disable \
- && fname) syncops_name(fname); \
- return ret; \
-} while (0)
-
#define SYNCOPS_NEXT_SMB_FNAME(op, fname, args) do { \
int ret; \
struct syncops_config_data *config; \
} while (0)
static int syncops_symlink(vfs_handle_struct *handle,
- const char *oldname, const char *newname)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- SYNCOPS_NEXT(SYMLINK, newname, (handle, oldname, newname));
+ int ret;
+ struct syncops_config_data *config;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct syncops_config_data,
+ return -1);
+
+ ret = SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
+ if (ret == 0 && config->onmeta && !config->disable) {
+ syncops_two_names(link_contents,
+ new_smb_fname->base_name);
+ }
+ return ret;
}
static int syncops_link(vfs_handle_struct *handle,
}
static int smb_time_audit_symlink(vfs_handle_struct *handle,
- const char *oldpath, const char *newpath)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
int result;
struct timespec ts1,ts2;
double timediff;
clock_gettime_mono(&ts1);
- result = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ result = SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
if (timediff > audit_timeout) {
- smb_time_audit_log_fname("symlink", timediff, newpath);
+ smb_time_audit_log_fname("symlink", timediff,
+ new_smb_fname->base_name);
}
return result;
}
static int um_symlink(vfs_handle_struct *handle,
- const char *oldpath,
- const char *newpath)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
int status;
- char *old_client_path = NULL;
- char *new_client_path = NULL;
+ char *client_link_contents = NULL;
+ struct smb_filename *new_client_fname = NULL;
DEBUG(10, ("Entering um_symlink\n"));
- if (!is_in_media_files(oldpath) && !is_in_media_files(newpath)) {
- return SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ if (!is_in_media_files(link_contents) &&
+ !is_in_media_files(new_smb_fname->base_name)) {
+ return SMB_VFS_NEXT_SYMLINK(handle,
+ link_contents,
+ new_smb_fname);
}
status = alloc_get_client_path(handle, talloc_tos(),
- oldpath, &old_client_path);
+ link_contents, &client_link_contents);
if (status != 0) {
goto err;
}
-
- status = alloc_get_client_path(handle, talloc_tos(),
- newpath, &new_client_path);
+ status = alloc_get_client_smb_fname(handle, talloc_tos(),
+ new_smb_fname, &new_client_fname);
if (status != 0) {
goto err;
}
status = SMB_VFS_NEXT_SYMLINK(handle,
- old_client_path,
- new_client_path);
+ client_link_contents,
+ new_client_fname);
err:
- TALLOC_FREE(new_client_path);
- TALLOC_FREE(old_client_path);
+ TALLOC_FREE(client_link_contents);
+ TALLOC_FREE(new_client_fname);
return status;
}
int i=0;
bool insert_comma = False;
bool ret = False;
+ struct smb_filename *smb_fname = NULL;
if(!junction_to_local_path(jucn, &path, &conn, &cwd)) {
return False;
DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n",
path, msdfs_link));
- if(SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) {
- if (errno == EEXIST) {
- struct smb_filename *smb_fname;
-
- smb_fname = synthetic_smb_fname(talloc_tos(),
- path,
- NULL,
- NULL,
- 0);
- if (smb_fname == NULL) {
- errno = ENOMEM;
- goto out;
- }
+ smb_fname = synthetic_smb_fname(talloc_tos(),
+ path,
+ NULL,
+ NULL,
+ 0);
+ if (smb_fname == NULL) {
+ errno = ENOMEM;
+ goto out;
+ }
+ if(SMB_VFS_SYMLINK(conn, msdfs_link, smb_fname) < 0) {
+ if (errno == EEXIST) {
if(SMB_VFS_UNLINK(conn, smb_fname)!=0) {
TALLOC_FREE(smb_fname);
goto out;
}
- TALLOC_FREE(smb_fname);
}
- if (SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) {
+ if (SMB_VFS_SYMLINK(conn, msdfs_link, smb_fname) < 0) {
DEBUG(1,("create_msdfs_link: symlink failed "
"%s -> %s\nError: %s\n",
path, msdfs_link, strerror(errno)));
ret = True;
out:
+ TALLOC_FREE(smb_fname);
vfs_ChDir(conn, cwd);
SMB_VFS_DISCONNECT(conn);
conn_free(conn);
struct smb_request *req,
const char *pdata,
int total_data,
- const struct smb_filename *smb_fname)
+ const struct smb_filename *new_smb_fname)
{
char *link_target = NULL;
- const char *newname = smb_fname->base_name;
TALLOC_CTX *ctx = talloc_tos();
/* Set a symbolic link. */
}
DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
- newname, link_target ));
+ new_smb_fname->base_name, link_target ));
- if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) {
+ if (SMB_VFS_SYMLINK(conn,link_target,new_smb_fname) != 0) {
return map_nt_error_from_unix(errno);
}
return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
}
-int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
- const char *newpath)
+int smb_vfs_call_symlink(struct vfs_handle_struct *handle,
+ const char *link_target,
+ const struct smb_filename *new_smb_fname)
{
VFS_FIND(symlink);
- return handle->fns->symlink_fn(handle, oldpath, newpath);
+ return handle->fns->symlink_fn(handle, link_target, new_smb_fname);
}
int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
+ struct smb_filename *new_smb_fname = NULL;
+
if (argc != 3) {
printf("Usage: symlink <path> <link>\n");
return NT_STATUS_OK;
}
- if (SMB_VFS_SYMLINK(vfs->conn, argv[1], argv[2]) == -1) {
+ new_smb_fname = synthetic_smb_fname_split(mem_ctx,
+ argv[2],
+ lp_posix_pathnames());
+ if (new_smb_fname == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (SMB_VFS_SYMLINK(vfs->conn, argv[1], new_smb_fname) == -1) {
printf("symlink: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}