1
0
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:
Jeremy Allison 2013-04-17 14:42:20 -07:00 committed by David Disseldorp
parent 95f7fc83b2
commit 5727bfa410

View File

@ -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;
}