mirror of
https://github.com/samba-team/samba.git
synced 2025-06-17 15:17:09 +03:00
Fix bug in old create temp SMB request. Only use VFS functions.
Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: David Disseldorp <ddiss@samba.org> Autobuild-User(master): David Disseldorp <ddiss@samba.org> Autobuild-Date(master): Sat Apr 20 21:13:36 CEST 2013 on sn-devel-104
This commit is contained in:
parent
95f7fc83b2
commit
5727bfa410
@ -2422,13 +2422,14 @@ void reply_ctemp(struct smb_request *req)
|
||||
{
|
||||
connection_struct *conn = req->conn;
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
char *wire_name = NULL;
|
||||
char *fname = NULL;
|
||||
uint32 fattr;
|
||||
files_struct *fsp;
|
||||
int oplock_request;
|
||||
int tmpfd;
|
||||
char *s;
|
||||
NTSTATUS status;
|
||||
int i;
|
||||
TALLOC_CTX *ctx = talloc_tos();
|
||||
|
||||
START_PROFILE(SMBctemp);
|
||||
@ -2441,80 +2442,89 @@ void reply_ctemp(struct smb_request *req)
|
||||
fattr = SVAL(req->vwv+0, 0);
|
||||
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
|
||||
|
||||
srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
|
||||
srvstr_get_path_req(ctx, req, &wire_name, (const char *)req->buf+1,
|
||||
STR_TERMINATE, &status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
goto out;
|
||||
}
|
||||
if (*fname) {
|
||||
fname = talloc_asprintf(ctx,
|
||||
"%s/TMXXXXXX",
|
||||
fname);
|
||||
} else {
|
||||
fname = talloc_strdup(ctx, "TMXXXXXX");
|
||||
}
|
||||
|
||||
if (!fname) {
|
||||
reply_nterror(req, NT_STATUS_NO_MEMORY);
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (*wire_name) {
|
||||
fname = talloc_asprintf(ctx,
|
||||
"%s/TMP%s",
|
||||
wire_name,
|
||||
generate_random_str_list(ctx, 5, "0123456789"));
|
||||
} else {
|
||||
fname = talloc_asprintf(ctx,
|
||||
"TMP%s",
|
||||
generate_random_str_list(ctx, 5, "0123456789"));
|
||||
}
|
||||
|
||||
status = filename_convert(ctx, conn,
|
||||
if (!fname) {
|
||||
reply_nterror(req, NT_STATUS_NO_MEMORY);
|
||||
goto out;
|
||||
}
|
||||
|
||||
status = filename_convert(ctx, conn,
|
||||
req->flags2 & FLAGS2_DFS_PATHNAMES,
|
||||
fname,
|
||||
0,
|
||||
NULL,
|
||||
&smb_fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
|
||||
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
|
||||
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
|
||||
ERRSRV, ERRbadpath);
|
||||
goto out;
|
||||
}
|
||||
reply_nterror(req, status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Create the file. */
|
||||
status = SMB_VFS_CREATE_FILE(
|
||||
conn, /* conn */
|
||||
req, /* req */
|
||||
0, /* root_dir_fid */
|
||||
smb_fname, /* fname */
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE, /* access_mask */
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
|
||||
FILE_CREATE, /* create_disposition*/
|
||||
0, /* create_options */
|
||||
fattr, /* file_attributes */
|
||||
oplock_request, /* oplock_request */
|
||||
0, /* allocation_size */
|
||||
0, /* private_flags */
|
||||
NULL, /* sd */
|
||||
NULL, /* ea_list */
|
||||
&fsp, /* result */
|
||||
NULL); /* pinfo */
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
|
||||
TALLOC_FREE(fname);
|
||||
TALLOC_FREE(smb_fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (open_was_deferred(req->sconn, req->mid)) {
|
||||
/* We have re-scheduled this call. */
|
||||
goto out;
|
||||
}
|
||||
reply_openerror(req, status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 10) {
|
||||
/* Collision after 10 times... */
|
||||
reply_nterror(req, status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmpfd = mkstemp(smb_fname->base_name);
|
||||
if (tmpfd == -1) {
|
||||
reply_nterror(req, map_nt_error_from_unix(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
SMB_VFS_STAT(conn, smb_fname);
|
||||
|
||||
/* We should fail if file does not exist. */
|
||||
status = SMB_VFS_CREATE_FILE(
|
||||
conn, /* conn */
|
||||
req, /* req */
|
||||
0, /* root_dir_fid */
|
||||
smb_fname, /* fname */
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE, /* access_mask */
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
|
||||
FILE_OPEN, /* create_disposition*/
|
||||
0, /* create_options */
|
||||
fattr, /* file_attributes */
|
||||
oplock_request, /* oplock_request */
|
||||
0, /* allocation_size */
|
||||
0, /* private_flags */
|
||||
NULL, /* sd */
|
||||
NULL, /* ea_list */
|
||||
&fsp, /* result */
|
||||
NULL); /* pinfo */
|
||||
|
||||
/* close fd from mkstemp() */
|
||||
close(tmpfd);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (open_was_deferred(req->sconn, req->mid)) {
|
||||
/* We have re-scheduled this call. */
|
||||
goto out;
|
||||
}
|
||||
reply_openerror(req, status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
reply_outbuf(req, 1, 0);
|
||||
SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
|
||||
|
||||
@ -2552,6 +2562,7 @@ void reply_ctemp(struct smb_request *req)
|
||||
fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
|
||||
out:
|
||||
TALLOC_FREE(smb_fname);
|
||||
TALLOC_FREE(wire_name);
|
||||
END_PROFILE(SMBctemp);
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user