The branch, v3-6-test has been updated
       via  61d591b Fix bug 9811 - Old DOS SMB CTEMP request uses a non-VFS 
function to access the filesystem.
      from  8bb8f00 Bug 9807 - wbinfo: fix segfault in wbinfo_pam_logon

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test


- Log -----------------------------------------------------------------
commit 61d591bb1eacbd7bcdf6a1c4abe8442edfece524
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Apr 18 11:19:20 2013 -0700

    Fix bug 9811 - Old DOS SMB CTEMP request uses a non-VFS function to access 
the filesystem.
    
    Fix bug in old create temp SMB request. Only use VFS functions.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/reply.c |  118 +++++++++++++++++++++++++++----------------------
 1 files changed, 65 insertions(+), 53 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 31f4e2f..ca3a08f 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2239,13 +2239,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);
@@ -2258,77 +2259,86 @@ 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;
                }
-               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);
+               /* 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->mid)) {
-                       /* We have re-scheduled this call. */
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (open_was_deferred(req->mid)) {
+                               /* We have re-scheduled this call. */
+                               goto out;
+                       }
+                       reply_openerror(req, status);
                        goto out;
                }
-               reply_openerror(req, status);
+
+               break;
+       }
+
+       if (i == 10) {
+               /* Collision after 10 times... */
+               reply_nterror(req, status);
                goto out;
        }
 
@@ -2369,6 +2379,8 @@ 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(fname);
+       TALLOC_FREE(wire_name);
        END_PROFILE(SMBctemp);
        return;
 }


-- 
Samba Shared Repository

Reply via email to