s3: Make all callers of SMB_VFS_CREATEFILE call unix_convert first
authorTim Prouty <tprouty@samba.org>
Fri, 5 Jun 2009 01:39:55 +0000 (18:39 -0700)
committerTim Prouty <tprouty@samba.org>
Wed, 10 Jun 2009 20:13:26 +0000 (13:13 -0700)
This step is a requirement to change SMB_VFS_CREATEFILE to take an
smb_filename struct.

source3/rpc_server/srv_srvsvc_nt.c
source3/smbd/nttrans.c
source3/smbd/reply.c
source3/smbd/smb2_create.c
source3/smbd/trans2.c

index 4f0e48bd9d0d80863836877cc2e4e18ea75e5f8b..2df72323511d47c7abae69ce9f0704bfcda3d5fa 100644 (file)
@@ -2032,6 +2032,8 @@ WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
                                  struct srvsvc_NetGetFileSecurity *r)
 {
+       struct smb_filename *smb_fname = NULL;
+       char *fname = NULL;
        SEC_DESC *psd = NULL;
        size_t sd_size;
        fstring servicename;
@@ -2065,12 +2067,25 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
                goto error_exit;
        }
 
+       nt_status = unix_convert(talloc_tos(), conn, r->in.file, &smb_fname,
+                                0);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               werr = ntstatus_to_werror(nt_status);
+               goto error_exit;
+       }
+
+       nt_status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               werr = ntstatus_to_werror(nt_status);
+               goto error_exit;
+       }
+
        nt_status = SMB_VFS_CREATE_FILE(
                conn,                                   /* conn */
                NULL,                                   /* req */
                0,                                      /* root_dir_fid */
-               r->in.file,                             /* fname */
-               CFF_DOS_PATH,                           /* create_file_flags */
+               fname,                                  /* fname */
+               0,                                      /* create_file_flags */
                FILE_READ_ATTRIBUTES,                   /* access_mask */
                FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
                FILE_OPEN,                              /* create_disposition*/
@@ -2086,7 +2101,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
-                        r->in.file));
+                        fname));
                werr = ntstatus_to_werror(nt_status);
                goto error_exit;
        }
@@ -2098,7 +2113,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
-                        "for file %s\n", r->in.file));
+                        "for file %s\n", fname));
                werr = ntstatus_to_werror(nt_status);
                goto error_exit;
        }
@@ -2121,7 +2136,8 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
        close_file(NULL, fsp, NORMAL_CLOSE);
        vfs_ChDir(conn, oldcwd);
        conn_free_internal(conn);
-       return WERR_OK;
+       werr = WERR_OK;
+       goto done;
 
 error_exit:
 
@@ -2137,6 +2153,9 @@ error_exit:
                conn_free_internal(conn);
        }
 
+ done:
+       TALLOC_FREE(smb_fname);
+
        return werr;
 }
 
@@ -2148,6 +2167,8 @@ error_exit:
 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
                                  struct srvsvc_NetSetFileSecurity *r)
 {
+       struct smb_filename *smb_fname = NULL;
+       char *fname = NULL;
        fstring servicename;
        files_struct *fsp = NULL;
        SMB_STRUCT_STAT st;
@@ -2180,12 +2201,25 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
                goto error_exit;
        }
 
+       nt_status = unix_convert(talloc_tos(), conn, r->in.file, &smb_fname,
+                                0);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               werr = ntstatus_to_werror(nt_status);
+               goto error_exit;
+       }
+
+       nt_status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               werr = ntstatus_to_werror(nt_status);
+               goto error_exit;
+       }
+
        nt_status = SMB_VFS_CREATE_FILE(
                conn,                                   /* conn */
                NULL,                                   /* req */
                0,                                      /* root_dir_fid */
-               r->in.file,                             /* fname */
-               CFF_DOS_PATH,                           /* create_file_flags */
+               fname,                                  /* fname */
+               0,                                      /* create_file_flags */
                FILE_WRITE_ATTRIBUTES,                  /* access_mask */
                FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
                FILE_OPEN,                              /* create_disposition*/
@@ -2201,7 +2235,7 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
-                        r->in.file));
+                        fname));
                werr = ntstatus_to_werror(nt_status);
                goto error_exit;
        }
@@ -2240,7 +2274,8 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
        close_file(NULL, fsp, NORMAL_CLOSE);
        vfs_ChDir(conn, oldcwd);
        conn_free_internal(conn);
-       return WERR_OK;
+       werr = WERR_OK;
+       goto done;
 
 error_exit:
 
@@ -2256,6 +2291,9 @@ error_exit:
                conn_free_internal(conn);
        }
 
+ done:
+       TALLOC_FREE(smb_fname);
+
        return werr;
 }
 
index 4c216cc6bef029e87cb597b32913611b3fc27b95..11d1c4b8a92352d9ed0aa76bd24936084e85eff2 100644 (file)
@@ -416,6 +416,7 @@ static void do_ntcreate_pipe_open(connection_struct *conn,
 void reply_ntcreate_and_X(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
+       struct smb_filename *smb_fname = NULL;
        char *fname = NULL;
        uint32 flags;
        uint32 access_mask;
@@ -429,7 +430,6 @@ void reply_ntcreate_and_X(struct smb_request *req)
           reply bits separately. */
        uint32 fattr=0;
        SMB_OFF_T file_len = 0;
-       SMB_STRUCT_STAT sbuf;
        int info = 0;
        files_struct *fsp = NULL;
        char *p = NULL;
@@ -443,8 +443,6 @@ void reply_ntcreate_and_X(struct smb_request *req)
 
        START_PROFILE(SMBntcreateX);
 
-       SET_STAT_INVALID(sbuf);
-
        if (req->wct < 24) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                return;
@@ -468,8 +466,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
 
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBntcreateX);
-               return;
+               goto out;
        }
 
        DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x "
@@ -498,12 +495,10 @@ void reply_ntcreate_and_X(struct smb_request *req)
        if (IS_IPC(conn)) {
                if (lp_nt_pipe_support()) {
                        do_ntcreate_pipe_open(conn, req);
-                       END_PROFILE(SMBntcreateX);
-                       return;
+                       goto out;
                }
                reply_doserror(req, ERRDOS, ERRnoaccess);
-               END_PROFILE(SMBntcreateX);
-               return;
+               goto out;
        }
 
        oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
@@ -512,12 +507,24 @@ void reply_ntcreate_and_X(struct smb_request *req)
                        ? BATCH_OPLOCK : 0;
        }
 
+       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               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 */
-               CFF_DOS_PATH,                           /* create_file_flags */
+               0,                                      /* create_file_flags */
                access_mask,                            /* access_mask */
                share_access,                           /* share_access */
                create_disposition,                     /* create_disposition*/
@@ -529,13 +536,12 @@ void reply_ntcreate_and_X(struct smb_request *req)
                NULL,                                   /* ea_list */
                &fsp,                                   /* result */
                &info,                                  /* pinfo */
-               &sbuf);                                 /* psbuf */
+               &smb_fname->st);                        /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call, no error. */
-                       END_PROFILE(SMBntcreateX);
-                       return;
+                       goto out;
                }
                if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
                        reply_botherror(req, status, ERRDOS, ERRfilexists);
@@ -543,8 +549,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
                else {
                        reply_nterror(req, status);
                }
-               END_PROFILE(SMBntcreateX);
-               return;
+               goto out;
        }
 
        /*
@@ -572,8 +577,8 @@ void reply_ntcreate_and_X(struct smb_request *req)
                oplock_granted = NO_OPLOCK_RETURN;
        }
 
-       file_len = sbuf.st_ex_size;
-       fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
+       file_len = smb_fname->st.st_ex_size;
+       fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
        if (fattr == 0) {
                fattr = FILE_ATTRIBUTE_NORMAL;
        }
@@ -606,9 +611,9 @@ void reply_ntcreate_and_X(struct smb_request *req)
        p += 4;
 
        /* Create time. */
-       c_timespec = sbuf.st_ex_btime;
-       a_timespec = sbuf.st_ex_atime;
-       m_timespec = sbuf.st_ex_mtime;
+       c_timespec = smb_fname->st.st_ex_btime;
+       a_timespec = smb_fname->st.st_ex_atime;
+       m_timespec = smb_fname->st.st_ex_mtime;
 
        if (lp_dos_filetime_resolution(SNUM(conn))) {
                dos_filetime_timespec(&c_timespec);
@@ -626,7 +631,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
        p += 8;
        SIVAL(p,0,fattr); /* File Attributes. */
        p += 4;
-       SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf));
+       SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&smb_fname->st));
        p += 8;
        SOFF_T(p,0,file_len);
        p += 8;
@@ -639,8 +644,8 @@ void reply_ntcreate_and_X(struct smb_request *req)
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
                uint32 perms = 0;
                p += 25;
-               if (fsp->is_directory
-                   || can_write_to_file(conn, fsp->fsp_name, &sbuf)) {
+               if (fsp->is_directory ||
+                   can_write_to_file(conn, fsp->fsp_name, &smb_fname->st)) {
                        perms = FILE_GENERIC_ALL;
                } else {
                        perms = FILE_GENERIC_READ|FILE_EXECUTE;
@@ -652,6 +657,8 @@ void reply_ntcreate_and_X(struct smb_request *req)
                 fsp->fnum, fsp->fsp_name));
 
        chain_reply(req);
+ out:
+       TALLOC_FREE(smb_fname);
        END_PROFILE(SMBntcreateX);
        return;
 }
@@ -837,13 +844,13 @@ static void call_nt_transact_create(connection_struct *conn,
                                    char **ppdata, uint32 data_count,
                                    uint32 max_data_count)
 {
+       struct smb_filename *smb_fname = NULL;
        char *fname = NULL;
        char *params = *ppparams;
        char *data = *ppdata;
        /* Breakout the oplock request bits so we can set the reply bits separately. */
        uint32 fattr=0;
        SMB_OFF_T file_len = 0;
-       SMB_STRUCT_STAT sbuf;
        int info = 0;
        files_struct *fsp = NULL;
        char *p = NULL;
@@ -868,8 +875,6 @@ static void call_nt_transact_create(connection_struct *conn,
        uint8_t oplock_granted;
        TALLOC_CTX *ctx = talloc_tos();
 
-       SET_STAT_INVALID(sbuf);
-
        DEBUG(5,("call_nt_transact_create\n"));
 
        /*
@@ -883,10 +888,10 @@ static void call_nt_transact_create(connection_struct *conn,
                                ppsetup, setup_count,
                                ppparams, parameter_count,
                                ppdata, data_count);
-                       return;
+                       goto out;
                }
                reply_doserror(req, ERRDOS, ERRnoaccess);
-               return;
+               goto out;
        }
 
        /*
@@ -896,7 +901,7 @@ static void call_nt_transact_create(connection_struct *conn,
        if(parameter_count < 54) {
                DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               return;
+               goto out;
        }
 
        flags = IVAL(params,0);
@@ -927,7 +932,7 @@ static void call_nt_transact_create(connection_struct *conn,
                           "%u, data_count = %u\n", (unsigned int)ea_len,
                           (unsigned int)sd_len, (unsigned int)data_count));
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               return;
+               goto out;
        }
 
        if (sd_len) {
@@ -941,7 +946,7 @@ static void call_nt_transact_create(connection_struct *conn,
                                   "unmarshall_sec_desc failed: %s\n",
                                   nt_errstr(status)));
                        reply_nterror(req, status);
-                       return;
+                       goto out;
                }
        }
 
@@ -951,7 +956,7 @@ static void call_nt_transact_create(connection_struct *conn,
                                   "EA's not supported.\n",
                                   (unsigned int)ea_len));
                        reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
-                       return;
+                       goto out;
                }
 
                if (ea_len < 10) {
@@ -959,7 +964,7 @@ static void call_nt_transact_create(connection_struct *conn,
                                  "too small (should be more than 10)\n",
                                  (unsigned int)ea_len ));
                        reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
+                       goto out;
                }
 
                /* We have already checked that ea_len <= data_count here. */
@@ -967,7 +972,7 @@ static void call_nt_transact_create(connection_struct *conn,
                                               ea_len);
                if (ea_list == NULL) {
                        reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
+                       goto out;
                }
        }
 
@@ -976,7 +981,7 @@ static void call_nt_transact_create(connection_struct *conn,
                        STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               return;
+               goto out;
        }
 
        oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
@@ -985,12 +990,24 @@ static void call_nt_transact_create(connection_struct *conn,
                        ? BATCH_OPLOCK : 0;
        }
 
+       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               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 */
-               CFF_DOS_PATH,                           /* create_file_flags */
+               0,                                      /* create_file_flags */
                access_mask,                            /* access_mask */
                share_access,                           /* share_access */
                create_disposition,                     /* create_disposition*/
@@ -1002,7 +1019,7 @@ static void call_nt_transact_create(connection_struct *conn,
                ea_list,                                /* ea_list */
                &fsp,                                   /* result */
                &info,                                  /* pinfo */
-               &sbuf);                                 /* psbuf */
+               &smb_fname->st);                        /* psbuf */
 
        if(!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
@@ -1010,7 +1027,7 @@ static void call_nt_transact_create(connection_struct *conn,
                        return;
                }
                reply_openerror(req, status);
-               return;
+               goto out;
        }
 
        /*
@@ -1038,8 +1055,8 @@ static void call_nt_transact_create(connection_struct *conn,
                oplock_granted = NO_OPLOCK_RETURN;
        }
 
-       file_len = sbuf.st_ex_size;
-       fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
+       file_len = smb_fname->st.st_ex_size;
+       fattr = dos_mode(conn, fsp->fsp_name, &smb_fname->st);
        if (fattr == 0) {
                fattr = FILE_ATTRIBUTE_NORMAL;
        }
@@ -1054,7 +1071,7 @@ static void call_nt_transact_create(connection_struct *conn,
        params = nttrans_realloc(ppparams, param_len);
        if(params == NULL) {
                reply_doserror(req, ERRDOS, ERRnomem);
-               return;
+               goto out;
        }
 
        p = params;
@@ -1072,9 +1089,9 @@ static void call_nt_transact_create(connection_struct *conn,
        p += 8;
 
        /* Create time. */
-       c_timespec = sbuf.st_ex_btime;
-       a_timespec = sbuf.st_ex_atime;
-       m_timespec = sbuf.st_ex_mtime;
+       c_timespec = smb_fname->st.st_ex_btime;
+       a_timespec = smb_fname->st.st_ex_atime;
+       m_timespec = smb_fname->st.st_ex_mtime;
 
        if (lp_dos_filetime_resolution(SNUM(conn))) {
                dos_filetime_timespec(&c_timespec);
@@ -1092,7 +1109,7 @@ static void call_nt_transact_create(connection_struct *conn,
        p += 8;
        SIVAL(p,0,fattr); /* File Attributes. */
        p += 4;
-       SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf));
+       SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st));
        p += 8;
        SOFF_T(p,0,file_len);
        p += 8;
@@ -1105,8 +1122,8 @@ static void call_nt_transact_create(connection_struct *conn,
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
                uint32 perms = 0;
                p += 25;
-               if (fsp->is_directory
-                   || can_write_to_file(conn, fsp->fsp_name, &sbuf)) {
+               if (fsp->is_directory ||
+                   can_write_to_file(conn, fsp->fsp_name, &smb_fname->st)) {
                        perms = FILE_GENERIC_ALL;
                } else {
                        perms = FILE_GENERIC_READ|FILE_EXECUTE;
@@ -1118,7 +1135,8 @@ static void call_nt_transact_create(connection_struct *conn,
 
        /* Send the required number of replies */
        send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
-
+ out:
+       TALLOC_FREE(smb_fname);
        return;
 }
 
index 70d5537e042f08f574d38a743c32865db2bd2578..844bcc1882a06f39ce1c3247a6039d42b36d5f62 100644 (file)
@@ -1702,12 +1702,12 @@ void reply_fclose(struct smb_request *req)
 void reply_open(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
+       struct smb_filename *smb_fname = NULL;
        char *fname = NULL;
        uint32 fattr=0;
        SMB_OFF_T size = 0;
        time_t mtime=0;
        int info;
-       SMB_STRUCT_STAT sbuf;
        files_struct *fsp;
        int oplock_request;
        int deny_mode;
@@ -1721,12 +1721,9 @@ void reply_open(struct smb_request *req)
 
        START_PROFILE(SMBopen);
 
-       SET_STAT_INVALID(sbuf);
-
        if (req->wct < 2) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBopen);
-               return;
+               goto out;
        }
 
        oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
@@ -1737,8 +1734,7 @@ void reply_open(struct smb_request *req)
                            STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBopen);
-               return;
+               goto out;
        }
 
        if (!map_open_params_to_ntcreate(
@@ -1749,12 +1745,24 @@ void reply_open(struct smb_request *req)
                return;
        }
 
+       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               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 */
-               CFF_DOS_PATH,                           /* create_file_flags */
+               0,                                      /* create_file_flags */
                access_mask,                            /* access_mask */
                share_mode,                             /* share_access */
                create_disposition,                     /* create_disposition*/
@@ -1766,29 +1774,26 @@ void reply_open(struct smb_request *req)
                NULL,                                   /* ea_list */
                &fsp,                                   /* result */
                &info,                                  /* pinfo */
-               &sbuf);                                 /* psbuf */
+               &smb_fname->st);                        /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       END_PROFILE(SMBopen);
-                       return;
+                       goto out;
                }
                reply_openerror(req, status);
-               END_PROFILE(SMBopen);
-               return;
+               goto out;
        }
 
-       size = sbuf.st_ex_size;
-       fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
-       mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+       size = smb_fname->st.st_ex_size;
+       fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
+       mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
 
        if (fattr & aDIR) {
                DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
                close_file(req, fsp, ERROR_CLOSE);
                reply_doserror(req, ERRDOS,ERRnoaccess);
-               END_PROFILE(SMBopen);
-               return;
+               goto out;
        }
 
        reply_outbuf(req, 7, 0);
@@ -1811,6 +1816,8 @@ void reply_open(struct smb_request *req)
                SCVAL(req->outbuf,smb_flg,
                      CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
        }
+ out:
+       TALLOC_FREE(smb_fname);
        END_PROFILE(SMBopen);
        return;
 }
@@ -1822,6 +1829,7 @@ void reply_open(struct smb_request *req)
 void reply_open_and_X(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
+       struct smb_filename *smb_fname = NULL;
        char *fname = NULL;
        uint16 open_flags;
        int deny_mode;
@@ -1838,7 +1846,6 @@ void reply_open_and_X(struct smb_request *req)
        int smb_ofun;
        uint32 fattr=0;
        int mtime=0;
-       SMB_STRUCT_STAT sbuf;
        int smb_action = 0;
        files_struct *fsp;
        NTSTATUS status;
@@ -1854,12 +1861,9 @@ void reply_open_and_X(struct smb_request *req)
 
        if (req->wct < 15) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBopenX);
-               return;
+               goto out;
        }
 
-       SET_STAT_INVALID(sbuf);
-
        open_flags = SVAL(req->vwv+2, 0);
        deny_mode = SVAL(req->vwv+3, 0);
        smb_attr = SVAL(req->vwv+5, 0);
@@ -1876,8 +1880,7 @@ void reply_open_and_X(struct smb_request *req)
                } else {
                        reply_doserror(req, ERRSRV, ERRaccess);
                }
-               END_PROFILE(SMBopenX);
-               return;
+               goto out;
        }
 
        /* XXXX we need to handle passed times, sattr and flags */
@@ -1885,16 +1888,26 @@ void reply_open_and_X(struct smb_request *req)
                        STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBopenX);
-               return;
+               goto out;
        }
 
        if (!map_open_params_to_ntcreate(
                    fname, deny_mode, smb_ofun, &access_mask,
                    &share_mode, &create_disposition, &create_options)) {
                reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
-               END_PROFILE(SMBopenX);
-               return;
+               goto out;
+       }
+
+       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               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(
@@ -1902,7 +1915,7 @@ void reply_open_and_X(struct smb_request *req)
                req,                                    /* req */
                0,                                      /* root_dir_fid */
                fname,                                  /* fname */
-               CFF_DOS_PATH,                           /* create_file_flags */
+               0,                                      /* create_file_flags */
                access_mask,                            /* access_mask */
                share_mode,                             /* share_access */
                create_disposition,                     /* create_disposition*/
@@ -1914,16 +1927,15 @@ void reply_open_and_X(struct smb_request *req)
                NULL,                                   /* ea_list */
                &fsp,                                   /* result */
                &smb_action,                            /* pinfo */
-               &sbuf);                                 /* psbuf */
+               &smb_fname->st);                        /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBopenX);
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       return;
+                       goto out;
                }
                reply_openerror(req, status);
-               return;
+               goto out;
        }
 
        /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
@@ -1933,26 +1945,24 @@ void reply_open_and_X(struct smb_request *req)
                if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
                        close_file(req, fsp, ERROR_CLOSE);
                        reply_nterror(req, NT_STATUS_DISK_FULL);
-                       END_PROFILE(SMBopenX);
-                       return;
+                       goto out;
                }
                retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
                if (retval < 0) {
                        close_file(req, fsp, ERROR_CLOSE);
                        reply_nterror(req, NT_STATUS_DISK_FULL);
-                       END_PROFILE(SMBopenX);
-                       return;
+                       goto out;
                }
-               sbuf.st_ex_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
+               smb_fname->st.st_ex_size =
+                   SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st);
        }
 
-       fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
-       mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+       fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
+       mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
        if (fattr & aDIR) {
                close_file(req, fsp, ERROR_CLOSE);
                reply_doserror(req, ERRDOS, ERRnoaccess);
-               END_PROFILE(SMBopenX);
-               return;
+               goto out;
        }
 
        /* If the caller set the extended oplock request bit
@@ -1996,7 +2006,7 @@ void reply_open_and_X(struct smb_request *req)
        } else {
                srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
        }
-       SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_ex_size);
+       SIVAL(req->outbuf,smb_vwv6,(uint32)smb_fname->st.st_ex_size);
        SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
        SSVAL(req->outbuf,smb_vwv11,smb_action);
 
@@ -2004,8 +2014,10 @@ void reply_open_and_X(struct smb_request *req)
                SIVAL(req->outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
        }
 
-       END_PROFILE(SMBopenX);
        chain_reply(req);
+ out:
+       TALLOC_FREE(smb_fname);
+       END_PROFILE(SMBopenX);
        return;
 }
 
@@ -2050,12 +2062,12 @@ void reply_ulogoffX(struct smb_request *req)
 void reply_mknew(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
+       struct smb_filename *smb_fname = NULL;
        char *fname = NULL;
        uint32 fattr = 0;
        struct smb_file_time ft;
        files_struct *fsp;
        int oplock_request = 0;
-       SMB_STRUCT_STAT sbuf;
        NTSTATUS status;
        uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
        uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
@@ -2065,12 +2077,10 @@ void reply_mknew(struct smb_request *req)
 
        START_PROFILE(SMBcreate);
        ZERO_STRUCT(ft);
-       SET_STAT_INVALID(sbuf);
 
         if (req->wct < 3) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBcreate);
-               return;
+               goto out;
        }
 
        fattr = SVAL(req->vwv+0, 0);
@@ -2083,8 +2093,7 @@ void reply_mknew(struct smb_request *req)
                            STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBcreate);
-               return;
+               goto out;
        }
 
        if (fattr & aVOLID) {
@@ -2100,12 +2109,24 @@ void reply_mknew(struct smb_request *req)
                create_disposition = FILE_OVERWRITE_IF;
        }
 
+       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               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 */
-               CFF_DOS_PATH,                           /* create_file_flags */
+               0,                              /* create_file_flags */
                access_mask,                            /* access_mask */
                share_mode,                             /* share_access */
                create_disposition,                     /* create_disposition*/
@@ -2117,24 +2138,23 @@ void reply_mknew(struct smb_request *req)
                NULL,                                   /* ea_list */
                &fsp,                                   /* result */
                NULL,                                   /* pinfo */
-               &sbuf);                                 /* psbuf */
+               &smb_fname->st);                        /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBcreate);
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       return;
+                       goto out;
                }
                reply_openerror(req, status);
-               return;
+               goto out;
        }
 
-       ft.atime = sbuf.st_ex_atime; /* atime. */
-       status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, &ft, true);
+       ft.atime = smb_fname->st.st_ex_atime; /* atime. */
+       status = smb_set_file_time(conn, fsp, fsp->fsp_name, &smb_fname->st,
+                                  &ft, true);
        if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBcreate);
-               reply_openerror(req, status);
-               return;
+               goto out;
        }
 
        reply_outbuf(req, 1, 0);
@@ -2154,6 +2174,8 @@ void reply_mknew(struct smb_request *req)
        DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
                    fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) );
 
+ out:
+       TALLOC_FREE(smb_fname);
        END_PROFILE(SMBcreate);
        return;
 }
index e264afab1402b0bd7610082e7d04429d8c6316ac..73c7cec63a527b666c04cf2a56f34999ae894900 100644 (file)
@@ -252,6 +252,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
        files_struct *result;
        int info;
        SMB_STRUCT_STAT sbuf;
+       struct smb_filename *smb_fname = NULL;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct smbd_smb2_create_state);
@@ -265,7 +266,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 
        smbreq = smbd_smb2_fake_smb_request(smb2req);
        if (tevent_req_nomem(smbreq, req)) {
-               return tevent_req_post(req, ev);
+               goto out;
        }
 
        if (IS_IPC(smbreq->conn)) {
@@ -273,7 +274,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 
                if (!lp_nt_pipe_support()) {
                        tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
-                       return tevent_req_post(req, ev);
+                       goto out;
                }
 
                /* Strip \\ off the name. */
@@ -284,7 +285,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                status = open_np_file(smbreq, pipe_name, &result);
                if (!NT_STATUS_IS_OK(status)) {
                        tevent_req_nterror(req, status);
-                       return tevent_req_post(req, ev);
+                       goto out;
                }
                info = FILE_WAS_OPENED;
                ZERO_STRUCT(sbuf);
@@ -292,7 +293,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                status = file_new(smbreq, smbreq->conn, &result);
                if(!NT_STATUS_IS_OK(status)) {
                        tevent_req_nterror(req, status);
-                       return tevent_req_post(req, ev);
+                       goto out;
                }
 
                status = print_fsp_open(smbreq,
@@ -304,19 +305,32 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                if (!NT_STATUS_IS_OK(status)) {
                        file_free(smbreq, result);
                        tevent_req_nterror(req, status);
-                       return tevent_req_post(req, ev);
+                       goto out;
                }
                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 */
 
+               status = unix_convert(talloc_tos(), smbreq->conn, in_name,
+                                     &smb_fname, 0);
+               if (!NT_STATUS_IS_OK(status)) {
+                       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 */
-                                            in_name,
-                                            CFF_DOS_PATH, /* create_file_flags */
+                                            fname,
+                                            0, /* create_file_flags */
                                             in_desired_access,
                                             in_share_access,
                                             in_create_disposition,
@@ -328,11 +342,12 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                                             NULL, /* ea_list */
                                             &result,
                                             &info,
-                                            &sbuf);
+                                            &smb_fname->st);
                if (!NT_STATUS_IS_OK(status)) {
                        tevent_req_nterror(req, status);
-                       return tevent_req_post(req, ev);
+                       goto out;
                }
+               sbuf = smb_fname->st;
        }
 
        smb2req->compat_chain_fsp = smbreq->chain_fsp;
@@ -359,6 +374,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
        state->out_file_id_volatile = result->fnum;
 
        tevent_req_done(req);
+ out:
+       TALLOC_FREE(smb_fname);
        return tevent_req_post(req, ev);
 }
 
index a8120d42fbe2d4de7fd39b6a63440f85b66a027e..a36e9f588accb532e06090df8c98909b9c8ab769 100644 (file)
@@ -869,6 +869,7 @@ static void call_trans2open(connection_struct *conn,
                            char **ppdata, int total_data,
                            unsigned int max_data_bytes)
 {
+       struct smb_filename *smb_fname = NULL;
        char *params = *pparams;
        char *pdata = *ppdata;
        int deny_mode;
@@ -886,7 +887,6 @@ static void call_trans2open(connection_struct *conn,
        SMB_OFF_T size=0;
        int fattr=0,mtime=0;
        SMB_INO_T inode = 0;
-       SMB_STRUCT_STAT sbuf;
        int smb_action = 0;
        files_struct *fsp;
        struct ea_list *ea_list = NULL;
@@ -898,15 +898,13 @@ static void call_trans2open(connection_struct *conn,
        uint32 create_options = 0;
        TALLOC_CTX *ctx = talloc_tos();
 
-       SET_STAT_INVALID(sbuf);
-
        /*
         * Ensure we have enough parameters to perform the operation.
         */
 
        if (total_params < 29) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               return;
+               goto out;
        }
 
        flags = SVAL(params, 0);
@@ -928,7 +926,7 @@ static void call_trans2open(connection_struct *conn,
 
        if (IS_IPC(conn)) {
                reply_doserror(req, ERRSRV, ERRaccess);
-               return;
+               goto out;
        }
 
        srvstr_get_path(ctx, params, req->flags2, &fname, pname,
@@ -936,7 +934,7 @@ static void call_trans2open(connection_struct *conn,
                        &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               return;
+               goto out;
        }
 
        DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
@@ -945,7 +943,7 @@ static void call_trans2open(connection_struct *conn,
 
        if (open_ofun == 0) {
                reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
-               return;
+               goto out;
        }
 
        if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
@@ -954,37 +952,49 @@ static void call_trans2open(connection_struct *conn,
                                &create_disposition,
                                &create_options)) {
                reply_doserror(req, ERRDOS, ERRbadaccess);
-               return;
+               goto out;
        }
 
        /* Any data in this call is an EA list. */
        if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
                reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
-               return;
+               goto out;
        }
 
        if (total_data != 4) {
                if (total_data < 10) {
                        reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
+                       goto out;
                }
 
                if (IVAL(pdata,0) > total_data) {
                        DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
                                IVAL(pdata,0), (unsigned int)total_data));
                        reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
+                       goto out;
                }
 
                ea_list = read_ea_list(talloc_tos(), pdata + 4,
                                       total_data - 4);
                if (!ea_list) {
                        reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
+                       goto out;
                }
        } else if (IVAL(pdata,0) != 4) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               return;
+               goto out;
+       }
+
+       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               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(
@@ -992,7 +1002,7 @@ static void call_trans2open(connection_struct *conn,
                req,                                    /* req */
                0,                                      /* root_dir_fid */
                fname,                                  /* fname */
-               CFF_DOS_PATH,                           /* create_file_flags */
+               0,                                      /* create_file_flags */
                access_mask,                            /* access_mask */
                share_mode,                             /* share_access */
                create_disposition,                     /* create_disposition*/
@@ -1004,32 +1014,32 @@ static void call_trans2open(connection_struct *conn,
                ea_list,                                /* ea_list */
                &fsp,                                   /* result */
                &smb_action,                            /* pinfo */
-               &sbuf);                                 /* psbuf */
+               &smb_fname->st);                        /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       return;
+                       goto out;
                }
                reply_openerror(req, status);
-               return;
+               goto out;
        }
 
-       size = get_file_size_stat(&sbuf);
-       fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
-       mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
-       inode = sbuf.st_ex_ino;
+       size = get_file_size_stat(&smb_fname->st);
+       fattr = dos_mode(conn, fsp->fsp_name, &smb_fname->st);
+       mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
+       inode = smb_fname->st.st_ex_ino;
        if (fattr & aDIR) {
                close_file(req, fsp, ERROR_CLOSE);
                reply_doserror(req, ERRDOS,ERRnoaccess);
-               return;
+               goto out;
        }
 
        /* Realloc the size of parameters and data we will return */
        *pparams = (char *)SMB_REALLOC(*pparams, 30);
        if(*pparams == NULL ) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
-               return;
+               goto out;
        }
        params = *pparams;
 
@@ -1061,6 +1071,8 @@ static void call_trans2open(connection_struct *conn,
 
        /* Send the required number of replies */
        send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
+ out:
+       TALLOC_FREE(smb_fname);
 }
 
 /*********************************************************