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 /source3/smbd | |
parent | 9d7c4ad7482d0c5cff6d15324f82767c851bbf43 (diff) | |
download | samba-04afa4b6b50f3a23a1872983c75653dc5f670279.tar.gz samba-04afa4b6b50f3a23a1872983c75653dc5f670279.tar.bz2 samba-04afa4b6b50f3a23a1872983c75653dc5f670279.zip |
s3: Plumb smb_filename through SMB_VFS_CREATE_FILE
Diffstat (limited to 'source3/smbd')
-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 |
6 files changed, 234 insertions, 257 deletions
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; |