1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

s3: VFS: Change SMB_VFS_SYMLINK to use const struct smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Richard Sharpe <realrichardsharpe@gmail.com>

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sun Jun 18 07:03:18 CEST 2017 on sn-devel-144
This commit is contained in:
Jeremy Allison 2017-06-08 16:25:58 -07:00
parent 6ae2d86b9c
commit 8e43af0f81
18 changed files with 186 additions and 132 deletions

View File

@ -476,8 +476,9 @@ static bool skel_getlock(vfs_handle_struct *handle, files_struct *fsp,
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;

View File

@ -570,10 +570,11 @@ static bool skel_getlock(vfs_handle_struct *handle, files_struct *fsp,
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,

View File

@ -226,6 +226,8 @@
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
@ -745,7 +747,9 @@ struct vfs_fn_pointers {
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,
@ -1251,8 +1255,9 @@ int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
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,

View File

@ -479,17 +479,44 @@ static int cap_ntimes(vfs_handle_struct *handle,
}
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,

View File

@ -1125,11 +1125,17 @@ static int cephwrap_linux_setlease(struct vfs_handle_struct *handle, files_struc
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);
}

View File

@ -2418,12 +2418,14 @@ static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
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;
}

View File

@ -1626,14 +1626,15 @@ static bool smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp,
}
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;
}

View File

@ -1234,9 +1234,12 @@ static bool vfs_gluster_getlock(struct vfs_handle_struct *handle,
}
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,

View File

@ -1719,47 +1719,41 @@ out:
* 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;
}

View File

@ -1150,19 +1150,28 @@ static int shadow_copy2_rename(vfs_handle_struct *handle,
}
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,
&timestamp_old, NULL, &snappath_old)) {
if (!shadow_copy2_strip_snapshot_internal(talloc_tos(),
handle,
link_contents,
&timestamp_old,
NULL,
&snappath_old)) {
return -1;
}
if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname,
&timestamp_new, NULL, &snappath_new)) {
if (!shadow_copy2_strip_snapshot_internal(talloc_tos(),
handle,
new_smb_fname->base_name,
&timestamp_new,
NULL,
&snappath_new)) {
return -1;
}
if ((timestamp_old != 0) || (timestamp_new != 0)) {
@ -1176,7 +1185,7 @@ static int shadow_copy2_symlink(vfs_handle_struct *handle,
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,

View File

@ -2037,23 +2037,31 @@ static int snapper_gmt_rename(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,
&timestamp_old, NULL)) {
if (!snapper_gmt_strip_snapshot(talloc_tos(),
handle,
link_contents,
&timestamp_old,
NULL)) {
return -1;
}
if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, newname,
&timestamp_new, NULL)) {
if (!snapper_gmt_strip_snapshot(talloc_tos(),
handle,
new_smb_fname->base_name,
&timestamp_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,

View File

@ -108,19 +108,6 @@ static void syncops_two_names(const char *name1, const char *name2)
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
*/
@ -158,20 +145,6 @@ static int syncops_rename(vfs_handle_struct *handle,
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; \
@ -186,9 +159,22 @@ static int syncops_rename(vfs_handle_struct *handle,
} 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,

View File

@ -1424,19 +1424,21 @@ static bool smb_time_audit_getlock(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;

View File

@ -1318,38 +1318,40 @@ err:
}
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;
}

View File

@ -1297,6 +1297,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
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;
@ -1339,27 +1340,24 @@ bool create_msdfs_link(const struct junction_map *jucn)
DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n",
path, msdfs_link));
if(SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) {
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) {
struct smb_filename *smb_fname;
smb_fname = synthetic_smb_fname(talloc_tos(),
path,
NULL,
NULL,
0);
if (smb_fname == NULL) {
errno = ENOMEM;
goto out;
}
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)));
@ -1370,6 +1368,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
ret = True;
out:
TALLOC_FREE(smb_fname);
vfs_ChDir(conn, cwd);
SMB_VFS_DISCONNECT(conn);
conn_free(conn);

View File

@ -6607,10 +6607,9 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *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. */
@ -6632,9 +6631,9 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
}
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);
}

View File

@ -2152,11 +2152,12 @@ int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
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,

View File

@ -1213,12 +1213,20 @@ static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
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;
}