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; connection_struct *conn = req->conn;
struct smb_filename *smb_fname = NULL; struct smb_filename *smb_fname = NULL;
char *wire_name = NULL;
char *fname = NULL; char *fname = NULL;
uint32 fattr; uint32 fattr;
files_struct *fsp; files_struct *fsp;
int oplock_request; int oplock_request;
int tmpfd;
char *s; char *s;
NTSTATUS status; NTSTATUS status;
int i;
TALLOC_CTX *ctx = talloc_tos(); TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBctemp); START_PROFILE(SMBctemp);
@ -2441,80 +2442,89 @@ void reply_ctemp(struct smb_request *req)
fattr = SVAL(req->vwv+0, 0); fattr = SVAL(req->vwv+0, 0);
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf); 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); STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status); reply_nterror(req, status);
goto out; goto out;
} }
if (*fname) {
fname = talloc_asprintf(ctx,
"%s/TMXXXXXX",
fname);
} else {
fname = talloc_strdup(ctx, "TMXXXXXX");
}
if (!fname) { for (i = 0; i < 10; i++) {
reply_nterror(req, NT_STATUS_NO_MEMORY); if (*wire_name) {
goto out; 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, req->flags2 & FLAGS2_DFS_PATHNAMES,
fname, fname,
0, 0,
NULL, NULL,
&smb_fname); &smb_fname);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath); ERRSRV, ERRbadpath);
goto out;
}
reply_nterror(req, status);
goto out; 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); reply_nterror(req, status);
goto out; 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); reply_outbuf(req, 1, 0);
SSVAL(req->outbuf,smb_vwv0,fsp->fnum); 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)); fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
out: out:
TALLOC_FREE(smb_fname); TALLOC_FREE(smb_fname);
TALLOC_FREE(wire_name);
END_PROFILE(SMBctemp); END_PROFILE(SMBctemp);
return; return;
} }