diff options
author | Tim Prouty <tprouty@samba.org> | 2009-06-12 12:54:11 -0700 |
---|---|---|
committer | Tim Prouty <tprouty@samba.org> | 2009-06-12 16:14:50 -0700 |
commit | 04afa4b6b50f3a23a1872983c75653dc5f670279 (patch) | |
tree | 05666ff5f2e91db0e49d00a111f2307e8c464850 | |
parent | 9d7c4ad7482d0c5cff6d15324f82767c851bbf43 (diff) | |
download | samba-04afa4b6b50f3a23a1872983c75653dc5f670279.tar.gz samba-04afa4b6b50f3a23a1872983c75653dc5f670279.tar.bz2 samba-04afa4b6b50f3a23a1872983c75653dc5f670279.zip |
s3: Plumb smb_filename through SMB_VFS_CREATE_FILE
-rw-r--r-- | source3/include/proto.h | 8 | ||||
-rw-r--r-- | source3/include/vfs.h | 10 | ||||
-rw-r--r-- | source3/include/vfs_macros.h | 6 | ||||
-rw-r--r-- | source3/modules/vfs_default.c | 14 | ||||
-rw-r--r-- | source3/modules/vfs_full_audit.c | 20 | ||||
-rw-r--r-- | source3/printing/nt_printing.c | 74 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 32 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 103 | ||||
-rw-r--r-- | source3/smbd/open.c | 115 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 15 | ||||
-rw-r--r-- | source3/smbd/reply.c | 149 | ||||
-rw-r--r-- | source3/smbd/smb2_create.c | 13 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 96 |
13 files changed, 292 insertions, 363 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index c39bb783e6..1c7ba8725a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6632,7 +6632,7 @@ NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn, SMB_STRUCT_STAT *psbuf, files_struct **result); NTSTATUS close_file_fchmod(struct smb_request *req, files_struct *fsp); NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, - const struct smb_filename *smb_dname); + struct smb_filename *smb_dname); void msg_file_was_renamed(struct messaging_context *msg, void *private_data, uint32_t msg_type, @@ -6646,8 +6646,7 @@ NTSTATUS open_streams_for_delete(connection_struct *conn, NTSTATUS create_file_default(connection_struct *conn, struct smb_request *req, uint16_t root_dir_fid, - const char *fname, - uint32_t create_file_flags, + struct smb_filename * smb_fname, uint32_t access_mask, uint32_t share_access, uint32_t create_disposition, @@ -6659,8 +6658,7 @@ NTSTATUS create_file_default(connection_struct *conn, struct ea_list *ea_list, files_struct **result, - int *pinfo, - SMB_STRUCT_STAT *psbuf); + int *pinfo); NTSTATUS get_relative_fid_filename(connection_struct *conn, struct smb_request *req, uint16_t root_dir_fid, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 9a736a7ca0..e0e022877a 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -117,8 +117,9 @@ /* Leave at 25 - not yet released. Add init_search_op call. - sdann */ /* Leave at 25 - not yet released. Add locking calls. -- zkirsch. */ /* Leave at 25 - not yet released. Add strict locking calls. -- drichards. */ +/* Changed to version 26 - Plumb struct smb_filename to SMB_VFS_CREATE_FILE. */ -#define SMB_VFS_INTERFACE_VERSION 25 +#define SMB_VFS_INTERFACE_VERSION 26 /* to bug old modules which are trying to compile with the old functions */ @@ -145,6 +146,7 @@ struct smb_request; struct ea_list; struct smb_file_time; struct blocking_lock_record; +struct smb_filename; /* Available VFS operations. These values must be in sync with vfs_ops struct @@ -332,8 +334,7 @@ struct vfs_ops { NTSTATUS (*create_file)(struct vfs_handle_struct *handle, struct smb_request *req, uint16_t root_dir_fid, - const char *fname, - uint32_t create_file_flags, + struct smb_filename *smb_fname, uint32_t access_mask, uint32_t share_access, uint32_t create_disposition, @@ -344,8 +345,7 @@ struct vfs_ops { struct security_descriptor *sd, struct ea_list *ea_list, files_struct **result, - int *pinfo, - SMB_STRUCT_STAT *psbuf); + int *pinfo); int (*close_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp); ssize_t (*vfs_read)(struct vfs_handle_struct *handle, struct files_struct *fsp, void *data, size_t n); ssize_t (*pread)(struct vfs_handle_struct *handle, struct files_struct *fsp, void *data, size_t n, SMB_OFF_T offset); diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 0b59f8f3ad..d888361dc4 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -49,7 +49,7 @@ /* File operations */ #define SMB_VFS_OPEN(conn, fname, fsp, flags, mode) (((conn)->vfs.ops.open)((conn)->vfs.handles.open, (fname), (fsp), (flags), (mode))) -#define SMB_VFS_CREATE_FILE(conn, req, root_dir_fid, fname, create_file_flags, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, allocation_size, sd, ea_list, result, pinfo, psbuf) (((conn)->vfs.ops.create_file)((conn)->vfs.handles.create_file, (req), (root_dir_fid), (fname), (create_file_flags), (access_mask), (share_access), (create_disposition), (create_options), (file_attributes), (oplock_request), (allocation_size), (sd), (ea_list), (result), (pinfo), (psbuf))) +#define SMB_VFS_CREATE_FILE(conn, req, root_dir_fid, smb_fname, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, allocation_size, sd, ea_list, result, pinfo) (((conn)->vfs.ops.create_file)((conn)->vfs.handles.create_file, (req), (root_dir_fid), (smb_fname), (access_mask), (share_access), (create_disposition), (create_options), (file_attributes), (oplock_request), (allocation_size), (sd), (ea_list), (result), (pinfo))) #define SMB_VFS_CLOSE(fsp) ((fsp)->conn->vfs.ops.close_fn((fsp)->conn->vfs.handles.close_hnd, (fsp))) #define SMB_VFS_READ(fsp, data, n) ((fsp)->conn->vfs.ops.vfs_read((fsp)->conn->vfs.handles.vfs_read, (fsp), (data), (n))) #define SMB_VFS_PREAD(fsp, data, n, off) ((fsp)->conn->vfs.ops.pread((fsp)->conn->vfs.handles.pread, (fsp), (data), (n), (off))) @@ -184,7 +184,7 @@ /* File operations */ #define SMB_VFS_OPAQUE_OPEN(conn, fname, fsp, flags, mode) (((conn)->vfs_opaque.ops.open)((conn)->vfs_opaque.handles.open, (fname), (fsp), (flags), (mode))) -#define SMB_VFS_OPAQUE_CREATE_FILE(conn, req, root_dir_fid, fname, create_file_flags, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, allocation_size, sd, ea_list, result, pinfo, psbuf) (((conn)->vfs_opaque.ops.create_file)((conn)->vfs_opaque.handles.create_file, (req), (root_dir_fid), (fname), (create_file_flags), (access_mask), (share_access), (create_disposition), (create_options), (file_attributes), (oplock_request), (allocation_size), (sd), (ea_list), (result), (pinfo), (psbuf))) +#define SMB_VFS_OPAQUE_CREATE_FILE(conn, req, root_dir_fid, smb_fname, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, allocation_size, sd, ea_list, result, pinfo) (((conn)->vfs_opaque.ops.create_file)((conn)->vfs_opaque.handles.create_file, (req), (root_dir_fid), (smb_fname), (access_mask), (share_access), (create_disposition), (create_options), (file_attributes), (oplock_request), (allocation_size), (sd), (ea_list), (result), (pinfo))) #define SMB_VFS_OPAQUE_CLOSE(fsp) ((fsp)->conn->vfs_opaque.ops.close_fn((fsp)->conn->vfs_opaque.handles.close_hnd, (fsp))) #define SMB_VFS_OPAQUE_READ(fsp, data, n) ((fsp)->conn->vfs_opaque.ops.vfs_read((fsp)->conn->vfs_opaque.handles.vfs_read, (fsp), (data), (n))) #define SMB_VFS_OPAQUE_PREAD(fsp, data, n, off) ((fsp)->conn->vfs_opaque.ops.pread((fsp)->conn->vfs_opaque.handles.pread, (fsp), (data), (n), (off))) @@ -320,7 +320,7 @@ /* File operations */ #define SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode) (((handle)->vfs_next.ops.open)((handle)->vfs_next.handles.open, (fname), (fsp), (flags), (mode))) -#define SMB_VFS_NEXT_CREATE_FILE(handle, req, root_dir_fid, fname, create_file_flags, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, allocation_size, sd, ea_list, result, pinfo, psbuf) (((handle)->vfs_next.ops.create_file)((handle)->vfs_next.handles.create_file, (req), (root_dir_fid), (fname), (create_file_flags), (access_mask), (share_access), (create_disposition), (create_options), (file_attributes), (oplock_request), (allocation_size), (sd), (ea_list), (result), (pinfo), (psbuf))) +#define SMB_VFS_NEXT_CREATE_FILE(handle, req, root_dir_fid, smb_fname, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, allocation_size, sd, ea_list, result, pinfo) (((handle)->vfs_next.ops.create_file)((handle)->vfs_next.handles.create_file, (req), (root_dir_fid), (smb_fname), (access_mask), (share_access), (create_disposition), (create_options), (file_attributes), (oplock_request), (allocation_size), (sd), (ea_list), (result), (pinfo))) #define SMB_VFS_NEXT_CLOSE(handle, fsp) ((handle)->vfs_next.ops.close_fn((handle)->vfs_next.handles.close_hnd, (fsp))) #define SMB_VFS_NEXT_READ(handle, fsp, data, n) ((handle)->vfs_next.ops.vfs_read((handle)->vfs_next.handles.vfs_read, (fsp), (data), (n))) #define SMB_VFS_NEXT_PREAD(handle, fsp, data, n, off) ((handle)->vfs_next.ops.pread((handle)->vfs_next.handles.pread, (fsp), (data), (n), (off))) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 4368dcd7da..28adce5768 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -228,8 +228,7 @@ static int vfswrap_open(vfs_handle_struct *handle, const char *fname, static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle, struct smb_request *req, uint16_t root_dir_fid, - const char *fname, - uint32_t create_file_flags, + struct smb_filename *smb_fname, uint32_t access_mask, uint32_t share_access, uint32_t create_disposition, @@ -240,15 +239,14 @@ static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle, struct security_descriptor *sd, struct ea_list *ea_list, files_struct **result, - int *pinfo, - SMB_STRUCT_STAT *psbuf) + int *pinfo) { - return create_file_default(handle->conn, req, root_dir_fid, fname, - create_file_flags, access_mask, share_access, + return create_file_default(handle->conn, req, root_dir_fid, smb_fname, + access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, - allocation_size, sd, ea_list, result, pinfo, - psbuf); + allocation_size, sd, ea_list, result, + pinfo); } static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp) diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index bbcb7b3364..e2d08b440f 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -115,8 +115,7 @@ static int smb_full_audit_open(vfs_handle_struct *handle, static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle, struct smb_request *req, uint16_t root_dir_fid, - const char *fname, - uint32_t create_file_flags, + struct smb_filename *smb_fname, uint32_t access_mask, uint32_t share_access, uint32_t create_disposition, @@ -127,8 +126,7 @@ static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle, struct security_descriptor *sd, struct ea_list *ea_list, files_struct **result, - int *pinfo, - SMB_STRUCT_STAT *psbuf); + int *pinfo); static int smb_full_audit_close(vfs_handle_struct *handle, files_struct *fsp); static ssize_t smb_full_audit_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n); @@ -1197,8 +1195,7 @@ static int smb_full_audit_open(vfs_handle_struct *handle, static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle, struct smb_request *req, uint16_t root_dir_fid, - const char *fname, - uint32_t create_file_flags, + struct smb_filename *smb_fname, uint32_t access_mask, uint32_t share_access, uint32_t create_disposition, @@ -1209,8 +1206,7 @@ static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle, struct security_descriptor *sd, struct ea_list *ea_list, files_struct **result_fsp, - int *pinfo, - SMB_STRUCT_STAT *psbuf) + int *pinfo) { NTSTATUS result; @@ -1218,8 +1214,7 @@ static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle, handle, /* handle */ req, /* req */ root_dir_fid, /* root_dir_fid */ - fname, /* fname */ - create_file_flags, /* create_file_flags */ + smb_fname, /* fname */ access_mask, /* access_mask */ share_access, /* share_access */ create_disposition, /* create_disposition*/ @@ -1230,11 +1225,10 @@ static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle, sd, /* sd */ ea_list, /* ea_list */ result_fsp, /* result */ - pinfo, /* pinfo */ - psbuf); /* psbuf */ + pinfo); /* pinfo */ do_log(SMB_VFS_OP_CREATE_FILE, (NT_STATUS_IS_OK(result)), handle, "0x%x|%s", - access_mask, fname); + access_mask, smb_fname_str_dbg(smb_fname)); return result; } diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 1aec954f12..74aaf0256c 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1277,7 +1277,6 @@ the modification date). Otherwise chose the numerically larger version number. static int file_version_is_newer(connection_struct *conn, fstring new_file, fstring old_file) { bool use_version = true; - char *filepath = NULL; uint32 new_major; uint32 new_minor; @@ -1290,13 +1289,11 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr struct smb_filename *smb_fname = NULL; files_struct *fsp = NULL; SMB_STRUCT_STAT st; - SMB_STRUCT_STAT stat_buf; NTSTATUS status; int ret; SET_STAT_INVALID(st); - SET_STAT_INVALID(stat_buf); new_create_time = (time_t)0; old_create_time = (time_t)0; @@ -1306,17 +1303,11 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr goto error_exit; } - status = get_full_smb_filename(talloc_tos(), smb_fname, &filepath); - if (!NT_STATUS_IS_OK(status)) { - goto error_exit; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ - filepath, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ FILE_GENERIC_READ, /* access_mask */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */ FILE_OPEN, /* create_disposition*/ @@ -1327,13 +1318,13 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - &stat_buf); /* psbuf */ + NULL); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { /* Old file not found, so by definition new file is in fact newer */ - DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n", - filepath, errno)); + DEBUG(10,("file_version_is_newer: Can't open old file [%s], " + "errno = %d\n", smb_fname_str_dbg(smb_fname), + errno)); ret = 1; goto done; @@ -1364,17 +1355,11 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr goto error_exit; } - status = get_full_smb_filename(talloc_tos(), smb_fname, &filepath); - if (!NT_STATUS_IS_OK(status)) { - goto error_exit; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ - filepath, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ FILE_GENERIC_READ, /* access_mask */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */ FILE_OPEN, /* create_disposition*/ @@ -1385,13 +1370,12 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - &stat_buf); /* psbuf */ + NULL); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { /* New file not found, this shouldn't occur if the caller did its job */ - DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n", - filepath, errno)); + DEBUG(3,("file_version_is_newer: Can't open new file [%s], " + "errno = %d\n", smb_fname_str_dbg(smb_fname), errno)); goto error_exit; } else { @@ -1466,15 +1450,12 @@ static uint32 get_correct_cversion(struct pipes_struct *p, struct smb_filename *smb_fname = NULL; char *driverpath = NULL; files_struct *fsp = NULL; - SMB_STRUCT_STAT st; connection_struct *conn = NULL; NTSTATUS status; char *oldcwd; fstring printdollar; int printdollar_snum; - SET_STAT_INVALID(st); - *perr = WERR_INVALID_PARAM; /* If architecture is Windows 95/98/ME, the version is always 0. */ @@ -1532,18 +1513,11 @@ static uint32 get_correct_cversion(struct pipes_struct *p, goto error_exit; } - status = get_full_smb_filename(talloc_tos(), smb_fname, &driverpath); - if (!NT_STATUS_IS_OK(status)) { - *perr = WERR_NOMEM; - goto error_exit; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ - driverpath, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ FILE_GENERIC_READ, /* access_mask */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */ FILE_OPEN, /* create_disposition*/ @@ -1554,22 +1528,25 @@ static uint32 get_correct_cversion(struct pipes_struct *p, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - &st); /* psbuf */ + NULL); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { - DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n", - driverpath, errno)); + DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = " + "%d\n", smb_fname_str_dbg(smb_fname), errno)); *perr = WERR_ACCESS_DENIED; goto error_exit; } else { uint32 major; uint32 minor; - int ret = get_file_version(fsp, driverpath, &major, &minor); + int ret; + + ret = get_file_version(fsp, smb_fname->base_name, &major, &minor); if (ret == -1) goto error_exit; if (!ret) { - DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath)); + DEBUG(6,("get_correct_cversion: Version info not " + "found [%s]\n", + smb_fname_str_dbg(smb_fname))); goto error_exit; } @@ -1587,17 +1564,20 @@ static uint32 get_correct_cversion(struct pipes_struct *p, break; default: - DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n", - driverpath, cversion)); + DEBUG(6,("get_correct_cversion: cversion " + "invalid [%s] cversion = %d\n", + smb_fname_str_dbg(smb_fname), + cversion)); goto error_exit; } - DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n", - driverpath, major, minor)); + DEBUG(10,("get_correct_cversion: Version info found [%s] major" + " = 0x%x minor = 0x%x\n", + smb_fname_str_dbg(smb_fname), major, minor)); } DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n", - driverpath, cversion)); + smb_fname_str_dbg(smb_fname), cversion)); goto done; diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 2df7232351..7887f81ba3 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -2033,7 +2033,6 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r) { struct smb_filename *smb_fname = NULL; - char *fname = NULL; SEC_DESC *psd = NULL; size_t sd_size; fstring servicename; @@ -2074,18 +2073,11 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, goto error_exit; } - nt_status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(nt_status)) { - werr = ntstatus_to_werror(nt_status); - goto error_exit; - } - nt_status = SMB_VFS_CREATE_FILE( conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ FILE_READ_ATTRIBUTES, /* access_mask */ FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */ FILE_OPEN, /* create_disposition*/ @@ -2096,12 +2088,11 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - NULL); /* psbuf */ + NULL); /* pinfo */ if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n", - fname)); + smb_fname_str_dbg(smb_fname))); werr = ntstatus_to_werror(nt_status); goto error_exit; } @@ -2113,7 +2104,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL " - "for file %s\n", fname)); + "for file %s\n", smb_fname_str_dbg(smb_fname))); werr = ntstatus_to_werror(nt_status); goto error_exit; } @@ -2168,7 +2159,6 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r) { struct smb_filename *smb_fname = NULL; - char *fname = NULL; fstring servicename; files_struct *fsp = NULL; SMB_STRUCT_STAT st; @@ -2208,18 +2198,11 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, goto error_exit; } - nt_status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(nt_status)) { - werr = ntstatus_to_werror(nt_status); - goto error_exit; - } - nt_status = SMB_VFS_CREATE_FILE( conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ FILE_WRITE_ATTRIBUTES, /* access_mask */ FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */ FILE_OPEN, /* create_disposition*/ @@ -2230,12 +2213,11 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - NULL); /* psbuf */ + NULL); /* pinfo */ if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n", - fname)); + smb_fname_str_dbg(smb_fname))); werr = ntstatus_to_werror(nt_status); goto error_exit; } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 11d1c4b8a9..7d0324bcda 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -513,18 +513,11 @@ void reply_ntcreate_and_X(struct smb_request *req) goto out; } - status = get_full_smb_filename(ctx, smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ root_dir_fid, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ access_mask, /* access_mask */ share_access, /* share_access */ create_disposition, /* create_disposition*/ @@ -535,8 +528,7 @@ void reply_ntcreate_and_X(struct smb_request *req) NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - &info, /* pinfo */ - &smb_fname->st); /* psbuf */ + &info); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { @@ -996,18 +988,11 @@ static void call_nt_transact_create(connection_struct *conn, goto out; } - status = get_full_smb_filename(ctx, smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ root_dir_fid, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ access_mask, /* access_mask */ share_access, /* share_access */ create_disposition, /* create_disposition*/ @@ -1018,8 +1003,7 @@ static void call_nt_transact_create(connection_struct *conn, sd, /* sd */ ea_list, /* ea_list */ &fsp, /* result */ - &info, /* pinfo */ - &smb_fname->st); /* psbuf */ + &info); /* pinfo */ if(!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { @@ -1173,8 +1157,8 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, const char *newname_in, uint32 attrs) { - struct smb_filename *smb_fname = NULL; - struct smb_filename *smb_fname_new = NULL; + struct smb_filename *smb_fname_src = NULL; + struct smb_filename *smb_fname_dst = NULL; char *oldname = NULL; char *newname = NULL; files_struct *fsp1,*fsp2; @@ -1189,75 +1173,71 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, goto out; } - status = unix_convert(ctx, conn, oldname_in, &smb_fname, 0); + status = unix_convert(ctx, conn, oldname_in, &smb_fname_src, 0); if (!NT_STATUS_IS_OK(status)) { goto out; } - status = get_full_smb_filename(ctx, smb_fname, &oldname); + status = check_name(conn, smb_fname_src->base_name); if (!NT_STATUS_IS_OK(status)) { goto out; } - status = check_name(conn, oldname); - if (!NT_STATUS_IS_OK(status)) { + /* Source must already exist. */ + if (!VALID_STAT(smb_fname_src->st)) { + status = NT_STATUS_OBJECT_NAME_NOT_FOUND; goto out; } - /* Source must already exist. */ - if (!VALID_STAT(smb_fname->st)) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + status = get_full_smb_filename(ctx, smb_fname_src, &oldname); + if (!NT_STATUS_IS_OK(status)) { goto out; } + /* Ensure attributes match. */ - fattr = dos_mode(conn, oldname, &smb_fname->st); + fattr = dos_mode(conn, oldname, &smb_fname_src->st); if ((fattr & ~attrs) & (aHIDDEN | aSYSTEM)) { status = NT_STATUS_NO_SUCH_FILE; goto out; } - status = unix_convert(ctx, conn, newname_in, &smb_fname_new, 0); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - - status = get_full_smb_filename(ctx, smb_fname_new, &newname); + status = unix_convert(ctx, conn, newname_in, &smb_fname_dst, 0); if (!NT_STATUS_IS_OK(status)) { goto out; } - status = check_name(conn, newname); + status = check_name(conn, smb_fname_dst->base_name); if (!NT_STATUS_IS_OK(status)) { goto out; } - /* Disallow if newname already exists. */ - if (VALID_STAT(smb_fname_new->st)) { + /* Disallow if dst file already exists. */ + if (VALID_STAT(smb_fname_dst->st)) { status = NT_STATUS_OBJECT_NAME_COLLISION; goto out; } /* No links from a directory. */ - if (S_ISDIR(smb_fname->st.st_ex_mode)) { + if (S_ISDIR(smb_fname_src->st.st_ex_mode)) { status = NT_STATUS_FILE_IS_A_DIRECTORY; goto out; } /* Ensure this is within the share. */ - status = check_reduced_name(conn, oldname); + status = check_reduced_name(conn, smb_fname_src->base_name); if (!NT_STATUS_IS_OK(status)) { goto out; } DEBUG(10,("copy_internals: doing file copy %s to %s\n", - oldname, newname)); + smb_fname_str_dbg(smb_fname_src), + smb_fname_str_dbg(smb_fname_dst))); status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - oldname, /* fname */ - 0, /* create_file_flags */ + smb_fname_src, /* fname */ FILE_READ_DATA, /* access_mask */ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ FILE_SHARE_DELETE), @@ -1269,8 +1249,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, NULL, /* sd */ NULL, /* ea_list */ &fsp1, /* result */ - &info, /* pinfo */ - &smb_fname->st); /* psbuf */ + &info); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { goto out; @@ -1280,8 +1259,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - newname, /* fname */ - 0, /* create_file_flags */ + smb_fname_dst, /* fname */ FILE_WRITE_DATA, /* access_mask */ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ FILE_SHARE_DELETE), @@ -1293,16 +1271,15 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, NULL, /* sd */ NULL, /* ea_list */ &fsp2, /* result */ - &info, /* pinfo */ - &smb_fname_new->st); /* psbuf */ + &info); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { close_file(NULL, fsp1, ERROR_CLOSE); goto out; } - if (smb_fname->st.st_ex_size) { - ret = vfs_transfer_file(fsp1, fsp2, smb_fname->st.st_ex_size); + if (smb_fname_src->st.st_ex_size) { + ret = vfs_transfer_file(fsp1, fsp2, smb_fname_src->st.st_ex_size); } /* @@ -1314,10 +1291,15 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, close_file(NULL, fsp1, NORMAL_CLOSE); /* Ensure the modtime is set correctly on the destination file. */ - set_close_write_time(fsp2, smb_fname->st.st_ex_mtime); + set_close_write_time(fsp2, smb_fname_src->st.st_ex_mtime); status = close_file(NULL, fsp2, NORMAL_CLOSE); + status = get_full_smb_filename(ctx, smb_fname_dst, &newname); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + /* Grrr. We have to do this as open_file_ntcreate adds aARCH when it creates the file. This isn't the correct thing to do in the copy case. JRA */ @@ -1325,21 +1307,26 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, status = NT_STATUS_NO_MEMORY; goto out; } - file_set_dosmode(conn, newname, fattr, &smb_fname_new->st, parent, + file_set_dosmode(conn, newname, fattr, &smb_fname_dst->st, parent, false); TALLOC_FREE(parent); - if (ret < (SMB_OFF_T)smb_fname->st.st_ex_size) { + if (ret < (SMB_OFF_T)smb_fname_src->st.st_ex_size) { status = NT_STATUS_DISK_FULL; goto out; } out: - TALLOC_FREE(smb_fname); - TALLOC_FREE(smb_fname_new); if (!NT_STATUS_IS_OK(status)) { DEBUG(3,("copy_internals: Error %s copy file %s to %s\n", - nt_errstr(status), oldname, newname)); + nt_errstr(status), smb_fname_str_dbg(smb_fname_src), + smb_fname_str_dbg(smb_fname_dst))); } + + TALLOC_FREE(smb_fname_src); + TALLOC_FREE(smb_fname_dst); + TALLOC_FREE(oldname); + TALLOC_FREE(newname); + return status; } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 718feb4996..c7d5979a85 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2202,6 +2202,7 @@ NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, files_struct **result) { + struct smb_filename *smb_fname = NULL; files_struct *fsp = NULL; NTSTATUS status; @@ -2214,12 +2215,17 @@ NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn, return status; } - status = SMB_VFS_CREATE_FILE( + status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = SMB_VFS_CREATE_FILE( conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ FILE_WRITE_DATA, /* access_mask */ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ FILE_SHARE_DELETE), @@ -2231,8 +2237,10 @@ NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - psbuf); /* psbuf */ + NULL); /* psbuf */ + + *psbuf = smb_fname->st; + TALLOC_FREE(smb_fname); /* * This is not a user visible file open. @@ -2599,23 +2607,16 @@ static NTSTATUS open_directory(connection_struct *conn, } NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, - const struct smb_filename *smb_dname) + struct smb_filename *smb_dname) { NTSTATUS status; files_struct *fsp; - char *directory = NULL; - - status = get_full_smb_filename(talloc_tos(), smb_dname, &directory); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - directory, /* fname */ - 0, /* create_file_flags */ + smb_dname, /* fname */ FILE_READ_ATTRIBUTES, /* access_mask */ FILE_SHARE_NONE, /* share_access */ FILE_CREATE, /* create_disposition*/ @@ -2626,14 +2627,12 @@ NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - NULL); /* psbuf */ + NULL); /* pinfo */ if (NT_STATUS_IS_OK(status)) { close_file(req, fsp, NORMAL_CLOSE); } - out: - TALLOC_FREE(directory); + return status; } @@ -2787,7 +2786,9 @@ NTSTATUS open_streams_for_delete(connection_struct *conn, } for (i=0; i<num_streams; i++) { - char *streamname; + struct smb_filename *smb_fname = NULL; + char *streamname = NULL; + SMB_STRUCT_STAT sbuf; if (strequal(stream_info[i].name, "::$DATA")) { streams[i] = NULL; @@ -2796,10 +2797,21 @@ NTSTATUS open_streams_for_delete(connection_struct *conn, streamname = talloc_asprintf(talloc_tos(), "%s%s", fname, stream_info[i].name); - if (streamname == NULL) { DEBUG(0, ("talloc_aprintf failed\n")); status = NT_STATUS_NO_MEMORY; + } + + if (SMB_VFS_STAT(conn, streamname, &sbuf) == -1) { + SET_STAT_INVALID(sbuf); + } + + TALLOC_FREE(streamname); + + status = create_synthetic_smb_fname(talloc_tos(), fname, + stream_info[i].name, + &sbuf, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { goto fail; } @@ -2807,8 +2819,7 @@ NTSTATUS open_streams_for_delete(connection_struct *conn, conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ - streamname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ DELETE_ACCESS, /* access_mask */ (FILE_SHARE_READ | /* share_access */ FILE_SHARE_WRITE | FILE_SHARE_DELETE), @@ -2820,16 +2831,17 @@ NTSTATUS open_streams_for_delete(connection_struct *conn, NULL, /* sd */ NULL, /* ea_list */ &streams[i], /* result */ - NULL, /* pinfo */ - NULL); /* psbuf */ - - TALLOC_FREE(streamname); + NULL); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("Could not open stream %s: %s\n", - streamname, nt_errstr(status))); + smb_fname_str_dbg(smb_fname), + nt_errstr(status))); + + TALLOC_FREE(smb_fname); break; } + TALLOC_FREE(smb_fname); } /* @@ -3323,8 +3335,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, NTSTATUS create_file_default(connection_struct *conn, struct smb_request *req, uint16_t root_dir_fid, - const char *fname, - uint32_t create_file_flags, + struct smb_filename *smb_fname, uint32_t access_mask, uint32_t share_access, uint32_t create_disposition, @@ -3336,13 +3347,11 @@ NTSTATUS create_file_default(connection_struct *conn, struct ea_list *ea_list, files_struct **result, - int *pinfo, - SMB_STRUCT_STAT *psbuf) + int *pinfo) { - struct case_semantics_state *case_state = NULL; - SMB_STRUCT_STAT sbuf; int info = FILE_WAS_OPENED; files_struct *fsp = NULL; + char *fname = NULL; NTSTATUS status; DEBUG(10,("create_file: access_mask = 0x%x " @@ -3350,7 +3359,7 @@ NTSTATUS create_file_default(connection_struct *conn, "create_disposition = 0x%x create_options = 0x%x " "oplock_request = 0x%x " "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, " - "create_file_flags = 0x%x, fname = %s\n", + "fname = %s\n", (unsigned int)access_mask, (unsigned int)file_attributes, (unsigned int)share_access, @@ -3358,7 +3367,7 @@ NTSTATUS create_file_default(connection_struct *conn, (unsigned int)create_options, (unsigned int)oplock_request, (unsigned int)root_dir_fid, - ea_list, sd, create_file_flags, fname)); + ea_list, sd, smb_fname_str_dbg(smb_fname))); /* MSDFS pathname processing must be done FIRST. MSDFS pathnames containing IPv6 addresses can @@ -3368,7 +3377,8 @@ NTSTATUS create_file_default(connection_struct *conn, if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) { char *resolved_fname; - status = resolve_dfspath(talloc_tos(), conn, true, fname, + status = resolve_dfspath(talloc_tos(), conn, true, + smb_fname->base_name, &resolved_fname); if (!NT_STATUS_IS_OK(status)) { @@ -3380,7 +3390,13 @@ NTSTATUS create_file_default(connection_struct *conn, */ goto fail; } - fname = resolved_fname; + TALLOC_FREE(smb_fname->base_name); + smb_fname->base_name = resolved_fname; + } + + status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); + if (!NT_STATUS_IS_OK(status)) { + goto fail; } /* @@ -3428,7 +3444,7 @@ NTSTATUS create_file_default(connection_struct *conn, goto fail; } - ZERO_STRUCT(sbuf); + ZERO_STRUCT(smb_fname->st); goto done; } @@ -3438,24 +3454,6 @@ NTSTATUS create_file_default(connection_struct *conn, } } - /* - * Check if POSIX semantics are wanted. - */ - - if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) { - case_state = set_posix_case_semantics(talloc_tos(), conn); - } - - if (psbuf != NULL) { - sbuf = *psbuf; - } else { - if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) { - SET_STAT_INVALID(sbuf); - } - } - - TALLOC_FREE(case_state); - /* All file access must go through check_name() */ status = check_name(conn, fname); @@ -3467,7 +3465,7 @@ NTSTATUS create_file_default(connection_struct *conn, conn, req, fname, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, allocation_size, sd, ea_list, - &fsp, &info, &sbuf); + &fsp, &info, &smb_fname->st); if (!NT_STATUS_IS_OK(status)) { goto fail; @@ -3480,9 +3478,6 @@ NTSTATUS create_file_default(connection_struct *conn, if (pinfo != NULL) { *pinfo = info; } - if (psbuf != NULL) { - *psbuf = sbuf; - } return NT_STATUS_OK; fail: diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 1029b764b5..2d0062ab94 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3459,6 +3459,7 @@ NTSTATUS append_parent_acl(files_struct *fsp, const SEC_DESC *pcsd, SEC_DESC **pp_new_sd) { + struct smb_filename *smb_dname = NULL; SEC_DESC *parent_sd = NULL; files_struct *parent_fsp = NULL; TALLOC_CTX *mem_ctx = talloc_tos(); @@ -3479,12 +3480,17 @@ NTSTATUS append_parent_acl(files_struct *fsp, return NT_STATUS_NO_MEMORY; } + status = create_synthetic_smb_fname_split(mem_ctx, parent_name, NULL, + &smb_dname); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + status = SMB_VFS_CREATE_FILE( fsp->conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ - parent_name, /* fname */ - 0, /* create_file_flags */ + smb_dname, /* fname */ FILE_READ_ATTRIBUTES, /* access_mask */ FILE_SHARE_NONE, /* share_access */ FILE_OPEN, /* create_disposition*/ @@ -3495,8 +3501,9 @@ NTSTATUS append_parent_acl(files_struct *fsp, NULL, /* sd */ NULL, /* ea_list */ &parent_fsp, /* result */ - &info, /* pinfo */ - NULL); /* psbuf */ + &info); /* pinfo */ + + TALLOC_FREE(smb_fname); if (!NT_STATUS_IS_OK(status)) { return status; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 3db11b9068..9c78b9bde0 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1783,18 +1783,11 @@ void reply_open(struct smb_request *req) goto out; } - status = get_full_smb_filename(ctx, smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ access_mask, /* access_mask */ share_mode, /* share_access */ create_disposition, /* create_disposition*/ @@ -1805,8 +1798,7 @@ void reply_open(struct smb_request *req) NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - &info, /* pinfo */ - &smb_fname->st); /* psbuf */ + &info); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { @@ -1936,18 +1928,11 @@ void reply_open_and_X(struct smb_request *req) goto out; } - status = get_full_smb_filename(ctx, smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ access_mask, /* access_mask */ share_mode, /* share_access */ create_disposition, /* create_disposition*/ @@ -1958,8 +1943,7 @@ void reply_open_and_X(struct smb_request *req) NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - &smb_action, /* pinfo */ - &smb_fname->st); /* psbuf */ + &smb_action); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { @@ -2147,18 +2131,11 @@ void reply_mknew(struct smb_request *req) goto out; } - status = get_full_smb_filename(ctx, smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ access_mask, /* access_mask */ share_mode, /* share_access */ create_disposition, /* create_disposition*/ @@ -2169,8 +2146,7 @@ void reply_mknew(struct smb_request *req) NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - &smb_fname->st); /* psbuf */ + NULL); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { @@ -2278,34 +2254,27 @@ void reply_ctemp(struct smb_request *req) goto out; } - status = get_full_smb_filename(ctx, smb_fname, &fname); + status = check_name(conn, smb_fname->base_name); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); goto out; } - status = check_name(conn, fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - - tmpfd = mkstemp(fname); + tmpfd = mkstemp(smb_fname->base_name); if (tmpfd == -1) { reply_unixerror(req, ERRDOS, ERRnoaccess); goto out; } SET_STAT_INVALID(smb_fname->st); - SMB_VFS_STAT(conn, fname, &smb_fname->st); + SMB_VFS_STAT(conn, smb_fname->base_name, &smb_fname->st); /* We should fail if file does not exist. */ status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ FILE_GENERIC_READ | FILE_GENERIC_WRITE, /* access_mask */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */ FILE_OPEN, /* create_disposition*/ @@ -2316,8 +2285,7 @@ void reply_ctemp(struct smb_request *req) NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - &smb_fname->st); /* psbuf */ + NULL); /* pinfo */ /* close fd from mkstemp() */ close(tmpfd); @@ -2519,8 +2487,7 @@ static NTSTATUS do_unlink(connection_struct *conn, (conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ DELETE_ACCESS, /* access_mask */ FILE_SHARE_NONE, /* share_access */ FILE_OPEN, /* create_disposition*/ @@ -2531,8 +2498,7 @@ static NTSTATUS do_unlink(connection_struct *conn, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - &smb_fname->st); /* psbuf */ + NULL); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("SMB_VFS_CREATEFILE failed: %s\n", @@ -6125,8 +6091,9 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, "directory = %s, newname = %s, " "last_component_dest = %s\n", conn->case_sensitive, conn->case_preserve, - conn->short_case_preserve, smb_fname_src->base_name, - smb_fname_dst->base_name, + conn->short_case_preserve, + smb_fname_str_dbg(smb_fname_src), + smb_fname_str_dbg(smb_fname_dst), smb_fname_dst->original_lcomp)); /* The dest name still may have wildcards. */ @@ -6163,12 +6130,13 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, create_options |= FILE_DIRECTORY_FILE; } + TALLOC_FREE(fname_src); + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname_src, /* fname */ - 0, /* create_file_flags */ + smb_fname_src, /* fname */ access_mask, /* access_mask */ (FILE_SHARE_READ | /* share_access */ FILE_SHARE_WRITE), @@ -6180,13 +6148,12 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - &smb_fname_src->st); /* psbuf */ + NULL); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Could not open rename source %s: %s\n", - fname_src, nt_errstr(status))); - TALLOC_FREE(fname_src); + smb_fname_str_dbg(smb_fname_src), + nt_errstr(status))); goto out; } @@ -6200,13 +6167,14 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, smb_fname_dst->original_lcomp, attrs, replace_if_exists); + TALLOC_FREE(fname_dst); + close_file(req, fsp, NORMAL_CLOSE); DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n", - nt_errstr(status), fname_src, fname_dst)); + nt_errstr(status), smb_fname_str_dbg(smb_fname_src), + smb_fname_str_dbg(smb_fname_dst))); - TALLOC_FREE(fname_src); - TALLOC_FREE(fname_dst); goto out; } @@ -6300,12 +6268,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, goto out; } - status = get_full_smb_filename(ctx, smb_fname_dst, &fname_dst); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(fname_src); - goto out; - } - ZERO_STRUCT(smb_fname_src->st); if (posix_pathnames) { SMB_VFS_LSTAT(conn, fname_src, &smb_fname_src->st); @@ -6313,6 +6275,8 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, SMB_VFS_STAT(conn, fname_src, &smb_fname_src->st); } + TALLOC_FREE(fname_src); + create_options = 0; if (S_ISDIR(smb_fname_src->st.st_ex_mode)) { @@ -6323,8 +6287,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname_src, /* fname */ - 0, /* create_file_flags */ + smb_fname_src, /* fname */ access_mask, /* access_mask */ (FILE_SHARE_READ | /* share_access */ FILE_SHARE_WRITE), @@ -6336,39 +6299,43 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - NULL, /* pinfo */ - &smb_fname_src->st); /* psbuf */ + NULL); /* pinfo */ if (!NT_STATUS_IS_OK(status)) { DEBUG(3,("rename_internals: SMB_VFS_CREATE_FILE " "returned %s rename %s -> %s\n", - nt_errstr(status), fname_src, fname_dst)); - TALLOC_FREE(fname_src); - TALLOC_FREE(fname_dst); + nt_errstr(status), + smb_fname_str_dbg(smb_fname_src), + smb_fname_str_dbg(smb_fname_dst))); break; } + status = get_full_smb_filename(ctx, smb_fname_dst, &fname_dst); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + status = rename_internals_fsp(conn, fsp, fname_dst, dname, attrs, replace_if_exists); + TALLOC_FREE(fname_dst); + close_file(req, fsp, NORMAL_CLOSE); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("rename_internals_fsp returned %s for " "rename %s -> %s\n", nt_errstr(status), - fname_src, fname_dst)); + smb_fname_str_dbg(smb_fname_src), + smb_fname_str_dbg(smb_fname_dst))); break; - TALLOC_FREE(fname_src); - TALLOC_FREE(fname_dst); } count++; DEBUG(3,("rename_internals: doing rename on %s -> " - "%s\n", fname_src, fname_dst)); + "%s\n", smb_fname_str_dbg(smb_fname_src), + smb_fname_str_dbg(smb_fname_src))); - TALLOC_FREE(fname_src); - TALLOC_FREE(fname_dst); } TALLOC_FREE(dir_hnd); @@ -6555,18 +6522,12 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, } } - status = get_full_smb_filename(talloc_tos(), smb_fname_src, &fname_src); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - /* Open the src file for reading. */ status = SMB_VFS_CREATE_FILE( conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ - fname_src, /* fname */ - 0, /* create_file_flags */ + smb_fname_src, /* fname */ FILE_GENERIC_READ, /* access_mask */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */ FILE_OPEN, /* create_disposition*/ @@ -6577,15 +6538,21 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, NULL, /* sd */ NULL, /* ea_list */ &fsp1, /* result */ - NULL, /* pinfo */ - &smb_fname_src->st); /* psbuf */ + NULL); /* psbuf */ + + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + status = get_full_smb_filename(talloc_tos(), smb_fname_src, &fname_src); if (!NT_STATUS_IS_OK(status)) { goto out; } dosattrs = dos_mode(conn, fname_src, &smb_fname_src->st); + TALLOC_FREE(fname_src); + status = get_full_smb_filename(talloc_tos(), smb_fname_dst_tmp, &fname_dst); if (!NT_STATUS_IS_OK(status)) { goto out; @@ -6595,13 +6562,14 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, ZERO_STRUCTP(&smb_fname_dst_tmp->st); } + TALLOC_FREE(fname_dst); + /* Open the dst file for writing. */ status = SMB_VFS_CREATE_FILE( conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ - fname_dst, /* fname */ - 0, /* create_file_flags */ + smb_fname_dst, /* fname */ FILE_GENERIC_WRITE, /* access_mask */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */ new_create_disposition, /* create_disposition*/ @@ -6612,8 +6580,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, NULL, /* sd */ NULL, /* ea_list */ &fsp2, /* result */ - NULL, /* pinfo */ - &smb_fname_dst_tmp->st); /* psbuf */ + NULL); /* psbuf */ if (!NT_STATUS_IS_OK(status)) { close_file(NULL, fsp1, ERROR_CLOSE); @@ -6662,8 +6629,6 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, out: TALLOC_FREE(smb_fname_dst_tmp); - TALLOC_FREE(fname_src); - TALLOC_FREE(fname_dst); return status; } diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 73c7cec63a..ad14b354a9 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -309,8 +309,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, } info = FILE_WAS_CREATED; } else { - char *fname = NULL; - /* these are ignored for SMB2 */ in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */ in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */ @@ -321,16 +319,10 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, goto out; } - status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - status = SMB_VFS_CREATE_FILE(smbreq->conn, smbreq, 0, /* root_dir_fid */ - fname, - 0, /* create_file_flags */ + smb_fname, in_desired_access, in_share_access, in_create_disposition, @@ -341,8 +333,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, NULL, /* security_descriptor */ NULL, /* ea_list */ &result, - &info, - &smb_fname->st); + &info); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); goto out; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index dc2544c4e3..977ef4e809 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -991,18 +991,11 @@ static void call_trans2open(connection_struct *conn, goto out; } - status = get_full_smb_filename(ctx, smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ access_mask, /* access_mask */ share_mode, /* share_access */ create_disposition, /* create_disposition*/ @@ -1013,8 +1006,7 @@ static void call_trans2open(connection_struct *conn, NULL, /* sd */ ea_list, /* ea_list */ &fsp, /* result */ - &smb_action, /* pinfo */ - &smb_fname->st); /* psbuf */ + &smb_action); /* psbuf */ if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { @@ -5080,6 +5072,7 @@ static NTSTATUS smb_set_file_size(connection_struct *conn, SMB_STRUCT_STAT *psbuf, SMB_OFF_T size) { + struct smb_filename *smb_fname = NULL; NTSTATUS status = NT_STATUS_OK; files_struct *new_fsp = NULL; @@ -5105,12 +5098,17 @@ static NTSTATUS smb_set_file_size(connection_struct *conn, return NT_STATUS_OK; } + status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ FILE_WRITE_ATTRIBUTES, /* access_mask */ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ FILE_SHARE_DELETE), @@ -5122,8 +5120,10 @@ static NTSTATUS smb_set_file_size(connection_struct *conn, NULL, /* sd */ NULL, /* ea_list */ &new_fsp, /* result */ - NULL, /* pinfo */ - psbuf); /* psbuf */ + NULL); /* pinfo */ + + *psbuf = smb_fname->st; + TALLOC_FREE(smb_fname); if (!NT_STATUS_IS_OK(status)) { /* NB. We check for open_was_deferred in the caller. */ @@ -5839,6 +5839,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf) { + struct smb_filename *smb_fname = NULL; uint64_t allocation_size = 0; NTSTATUS status = NT_STATUS_OK; files_struct *new_fsp = NULL; @@ -5890,12 +5891,17 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn, /* Pathname or stat or directory file. */ - status = SMB_VFS_CREATE_FILE( + status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ FILE_WRITE_DATA, /* access_mask */ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ FILE_SHARE_DELETE), @@ -5907,8 +5913,10 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn, NULL, /* sd */ NULL, /* ea_list */ &new_fsp, /* result */ - NULL, /* pinfo */ - psbuf); /* psbuf */ + NULL); /* pinfo */ + + *psbuf = smb_fname->st; + TALLOC_FREE(smb_fname); if (!NT_STATUS_IS_OK(status)) { /* NB. We check for open_was_deferred in the caller. */ @@ -6311,6 +6319,7 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, SMB_STRUCT_STAT *psbuf, int *pdata_return_size) { + struct smb_filename *smb_fname; NTSTATUS status = NT_STATUS_OK; uint32 raw_unixmode = 0; uint32 mod_unixmode = 0; @@ -6337,12 +6346,17 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n", fname, (unsigned int)unixmode )); - status = SMB_VFS_CREATE_FILE( + status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ FILE_READ_ATTRIBUTES, /* access_mask */ FILE_SHARE_NONE, /* share_access */ FILE_CREATE, /* create_disposition*/ @@ -6353,8 +6367,10 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - &info, /* pinfo */ - psbuf); /* psbuf */ + &info); /* pinfo */ + + *psbuf = smb_fname->st; + TALLOC_FREE(smb_fname); if (NT_STATUS_IS_OK(status)) { close_file(req, fsp, NORMAL_CLOSE); @@ -6414,6 +6430,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn, SMB_STRUCT_STAT *psbuf, int *pdata_return_size) { + struct smb_filename *smb_fname = NULL; bool extended_oplock_granted = False; char *pdata = *ppdata; uint32 flags = 0; @@ -6513,12 +6530,17 @@ static NTSTATUS smb_posix_open(connection_struct *conn, (unsigned int)wire_open_mode, (unsigned int)unixmode )); + status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ access_mask, /* access_mask */ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ FILE_SHARE_DELETE), @@ -6530,8 +6552,10 @@ static NTSTATUS smb_posix_open(connection_struct *conn, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - &info, /* pinfo */ - psbuf); /* psbuf */ + &info); /* pinfo */ + + *psbuf = smb_fname->st; + TALLOC_FREE(smb_fname); if (!NT_STATUS_IS_OK(status)) { return status; @@ -6611,6 +6635,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf) { + struct smb_filename *smb_fname = NULL; NTSTATUS status = NT_STATUS_OK; files_struct *fsp = NULL; uint16 flags = 0; @@ -6643,12 +6668,17 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, create_options |= FILE_DIRECTORY_FILE; } + status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ 0, /* root_dir_fid */ - fname, /* fname */ - 0, /* create_file_flags */ + smb_fname, /* fname */ DELETE_ACCESS, /* access_mask */ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ FILE_SHARE_DELETE), @@ -6660,8 +6690,10 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, NULL, /* sd */ NULL, /* ea_list */ &fsp, /* result */ - &info, /* pinfo */ - psbuf); /* psbuf */ + &info); /* pinfo */ + + *psbuf = smb_fname->st; + TALLOC_FREE(smb_fname); if (!NT_STATUS_IS_OK(status)) { return status; |