We've already checked fsp must be non-null here.
[mat/samba.git] / source3 / smbd / trans2.c
index 46f2aa03683f974500422b42a3e2e0335a3db5c1..05c180fc5dbc4f2dd3963053b07108a418acbeab 100644 (file)
@@ -35,6 +35,7 @@
 #include "trans2.h"
 #include "auth.h"
 #include "smbprofile.h"
+#include "rpc_server/srv_pipe_hnd.h"
 
 #define DIR_ENTRY_SAFETY_MARGIN 4096
 
@@ -106,7 +107,7 @@ static bool samba_private_attr_name(const char *unix_ea_name)
                if (strequal( prohibited_ea_names[i], unix_ea_name))
                        return true;
        }
-       if (StrnCaseCmp(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
+       if (strncasecmp_m(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
                        strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
                return true;
        }
@@ -128,7 +129,7 @@ NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
 
  again:
 
-       val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
+       val = talloc_realloc(mem_ctx, val, char, attr_size);
        if (!val) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -191,7 +192,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
         * TALLOC the result early to get the talloc hierarchy right.
         */
 
-       names = TALLOC_ARRAY(mem_ctx, char *, 1);
+       names = talloc_array(mem_ctx, char *, 1);
        if (names == NULL) {
                DEBUG(0, ("talloc failed\n"));
                return NT_STATUS_NO_MEMORY;
@@ -199,7 +200,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
 
        while (ea_namelist_size <= 65536) {
 
-               ea_namelist = TALLOC_REALLOC_ARRAY(
+               ea_namelist = talloc_realloc(
                        names, ea_namelist, char, ea_namelist_size);
                if (ea_namelist == NULL) {
                        DEBUG(0, ("talloc failed\n"));
@@ -258,7 +259,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
                num_names += 1;
        }
 
-       tmp = TALLOC_REALLOC_ARRAY(mem_ctx, names, char *, num_names);
+       tmp = talloc_realloc(mem_ctx, names, char *, num_names);
        if (tmp == NULL) {
                DEBUG(0, ("talloc failed\n"));
                TALLOC_FREE(names);
@@ -315,7 +316,7 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str
                    || samba_private_attr_name(names[i]))
                        continue;
 
-               listp = TALLOC_P(mem_ctx, struct ea_list);
+               listp = talloc(mem_ctx, struct ea_list);
                if (listp == NULL) {
                        return NULL;
                }
@@ -387,7 +388,7 @@ static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned in
                SCVAL(p,0,ea_list->ea.flags);
                SCVAL(p,1,dos_namelen);
                SSVAL(p,2,ea_list->ea.value.length);
-               fstrcpy(p+4, dos_ea_name);
+               strlcpy(p+4, dos_ea_name, dos_namelen+1);
                memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
 
                total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
@@ -451,7 +452,7 @@ static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
                SCVAL(p, 0x04, ea_list->ea.flags);
                SCVAL(p, 0x05, dos_namelen);
                SSVAL(p, 0x06, ea_list->ea.value.length);
-               fstrcpy((char *)(p+0x08), dos_ea_name);
+               strlcpy((char *)(p+0x08), dos_ea_name, dos_namelen+1);
                memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
 
                total_data_size -= this_size;
@@ -490,7 +491,7 @@ static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, con
                if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
                        DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
                                &unix_ea_name[5], ea_list->ea.name));
-                       safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
+                       strlcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-5);
                        break;
                }
        }
@@ -589,7 +590,7 @@ static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, siz
        size_t converted_size, offset = 0;
 
        while (offset + 2 < data_size) {
-               struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
+               struct ea_list *eal = talloc_zero(ctx, struct ea_list);
                unsigned int namelen = CVAL(pdata,offset);
 
                offset++; /* Go past the namelen byte. */
@@ -627,7 +628,7 @@ static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, siz
 
 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
 {
-       struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
+       struct ea_list *eal = talloc_zero(ctx, struct ea_list);
        uint16 val_len;
        unsigned int namelen;
        size_t converted_size;
@@ -1081,7 +1082,8 @@ static void call_trans2open(connection_struct *conn,
                goto out;
        }
 
-       if (!map_open_params_to_ntcreate(smb_fname, deny_mode, open_ofun,
+       if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
+                                        open_ofun,
                                         &access_mask, &share_mode,
                                         &create_disposition,
                                         &create_options,
@@ -1136,7 +1138,7 @@ static void call_trans2open(connection_struct *conn,
                &smb_action);                           /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
-               if (open_was_deferred(req->mid)) {
+               if (open_was_deferred(req->sconn, req->mid)) {
                        /* We have re-scheduled this call. */
                        goto out;
                }
@@ -1218,7 +1220,7 @@ static bool exact_match(bool has_wild,
        if (case_sensitive) {
                return strcmp(str,mask)==0;
        } else {
-               return StrCaseCmp(str,mask) == 0;
+               return strcasecmp_m(str,mask) == 0;
        }
 }
 
@@ -2268,6 +2270,7 @@ static void call_trans2findfirst(connection_struct *conn,
        TALLOC_CTX *ctx = talloc_tos();
        struct dptr_struct *dirptr = NULL;
        struct smbd_server_connection *sconn = req->sconn;
+       uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP);
 
        if (total_params < 13) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@@ -2311,6 +2314,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                                reply_nterror(req, NT_STATUS_INVALID_LEVEL);
                                goto out;
                        }
+                       ucf_flags |= UCF_UNIX_NAME_LOOKUP;
                        break;
                default:
                        reply_nterror(req, NT_STATUS_INVALID_LEVEL);
@@ -2328,8 +2332,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
        ntstatus = filename_convert(ctx, conn,
                                    req->flags2 & FLAGS2_DFS_PATHNAMES,
                                    directory,
-                                   (UCF_SAVE_LCOMP |
-                                       UCF_ALWAYS_ALLOW_WCARD_LCOMP),
+                                   ucf_flags,
                                    &mask_contains_wcard,
                                    &smb_dname);
        if (!NT_STATUS_IS_OK(ntstatus)) {
@@ -3208,7 +3211,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                                DEBUG(0,("set_user_quota: access_denied "
                                         "service [%s] user [%s]\n",
                                         lp_servicename(SNUM(conn)),
-                                        conn->session_info->unix_name));
+                                        conn->session_info->unix_info->unix_name));
                                return NT_STATUS_ACCESS_DENIED;
                        }
 
@@ -3385,7 +3388,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                            + 4 /* num_sids */
                            + 4 /* SID bytes */
                            + 4 /* pad/reserved */
-                           + (conn->session_info->utok.ngroups * 8)
+                           + (conn->session_info->unix_token->ngroups * 8)
                                /* groups list */
                            + (conn->session_info->security_token->num_sids *
                                    SID_MAX_SIZE)
@@ -3394,9 +3397,9 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                        SIVAL(pdata, 0, flags);
                        SIVAL(pdata, 4, SMB_WHOAMI_MASK);
                        SBIG_UINT(pdata, 8,
-                                 (uint64_t)conn->session_info->utok.uid);
+                                 (uint64_t)conn->session_info->unix_token->uid);
                        SBIG_UINT(pdata, 16,
-                                 (uint64_t)conn->session_info->utok.gid);
+                                 (uint64_t)conn->session_info->unix_token->gid);
 
 
                        if (data_len >= max_data_bytes) {
@@ -3411,7 +3414,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                                break;
                        }
 
-                       SIVAL(pdata, 24, conn->session_info->utok.ngroups);
+                       SIVAL(pdata, 24, conn->session_info->unix_token->ngroups);
                        SIVAL(pdata, 28, conn->session_info->security_token->num_sids);
 
                        /* We walk the SID list twice, but this call is fairly
@@ -3433,9 +3436,9 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                        data_len = 40;
 
                        /* GID list */
-                       for (i = 0; i < conn->session_info->utok.ngroups; ++i) {
+                       for (i = 0; i < conn->session_info->unix_token->ngroups; ++i) {
                                SBIG_UINT(pdata, data_len,
-                                         (uint64_t)conn->session_info->utok.groups[i]);
+                                         (uint64_t)conn->session_info->unix_token->groups[i]);
                                data_len += 8;
                        }
 
@@ -3537,6 +3540,7 @@ static void call_trans2setfsinfo(connection_struct *conn,
                                 char **ppdata, int total_data,
                                 unsigned int max_data_bytes)
 {
+       struct smbd_server_connection *sconn = req->sconn;
        char *pdata = *ppdata;
        char *params = *pparams;
        uint16 info_level;
@@ -3577,54 +3581,52 @@ static void call_trans2setfsinfo(connection_struct *conn,
 
        switch(info_level) {
                case SMB_SET_CIFS_UNIX_INFO:
-                       {
-                               uint16 client_unix_major;
-                               uint16 client_unix_minor;
-                               uint32 client_unix_cap_low;
-                               uint32 client_unix_cap_high;
-
-                               if (!lp_unix_extensions()) {
-                                       reply_nterror(req,
-                                                     NT_STATUS_INVALID_LEVEL);
-                                       return;
-                               }
+                       if (!lp_unix_extensions()) {
+                               reply_nterror(req,
+                                             NT_STATUS_INVALID_LEVEL);
+                               return;
+                       }
 
-                               /* There should be 12 bytes of capabilities set. */
-                               if (total_data < 8) {
-                                       reply_nterror(
-                                               req,
-                                               NT_STATUS_INVALID_PARAMETER);
-                                       return;
-                               }
-                               client_unix_major = SVAL(pdata,0);
-                               client_unix_minor = SVAL(pdata,2);
-                               client_unix_cap_low = IVAL(pdata,4);
-                               client_unix_cap_high = IVAL(pdata,8);
-                               /* Just print these values for now. */
-                               DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
-cap_low = 0x%x, cap_high = 0x%x\n",
-                                       (unsigned int)client_unix_major,
-                                       (unsigned int)client_unix_minor,
-                                       (unsigned int)client_unix_cap_low,
-                                       (unsigned int)client_unix_cap_high ));
-
-                               /* Here is where we must switch to posix pathname processing... */
-                               if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
-                                       lp_set_posix_pathnames();
-                                       mangle_change_to_posix();
-                               }
+                       /* There should be 12 bytes of capabilities set. */
+                       if (total_data < 8) {
+                               reply_nterror(
+                                       req,
+                                       NT_STATUS_INVALID_PARAMETER);
+                               return;
+                       }
+                       sconn->smb1.unix_info.client_major = SVAL(pdata,0);
+                       sconn->smb1.unix_info.client_minor = SVAL(pdata,2);
+                       sconn->smb1.unix_info.client_cap_low = IVAL(pdata,4);
+                       sconn->smb1.unix_info.client_cap_high = IVAL(pdata,8);
+                       /* Just print these values for now. */
+                       DEBUG(10, ("call_trans2setfsinfo: set unix_info info. "
+                                  "major = %u, minor = %u cap_low = 0x%x, "
+                                  "cap_high = 0x%xn",
+                                  (unsigned int)sconn->
+                                  smb1.unix_info.client_major,
+                                  (unsigned int)sconn->
+                                  smb1.unix_info.client_minor,
+                                  (unsigned int)sconn->
+                                  smb1.unix_info.client_cap_low,
+                                  (unsigned int)sconn->
+                                  smb1.unix_info.client_cap_high));
+
+                       /* Here is where we must switch to posix pathname processing... */
+                       if (sconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+                               lp_set_posix_pathnames();
+                               mangle_change_to_posix();
+                       }
 
-                               if ((client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
-                                   !(client_unix_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
-                                       /* Client that knows how to do posix locks,
-                                        * but not posix open/mkdir operations. Set a
-                                        * default type for read/write checks. */
+                       if ((sconn->smb1.unix_info.client_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
+                           !(sconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
+                               /* Client that knows how to do posix locks,
+                                * but not posix open/mkdir operations. Set a
+                                * default type for read/write checks. */
 
-                                       lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
+                               lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
 
-                               }
-                               break;
                        }
+                       break;
 
                case SMB_REQUEST_TRANSPORT_ENCRYPTION:
                        {
@@ -3683,9 +3685,11 @@ cap_low = 0x%x, cap_high = 0x%x\n",
                                         * encryption is now *on*. */
                                        status = srv_encryption_start(conn);
                                        if (!NT_STATUS_IS_OK(status)) {
-                                               exit_server_cleanly(
-                                                       "Failure in setting "
-                                                       "up encrypted transport");
+                                               char *reason = talloc_asprintf(talloc_tos(),
+                                                                              "Failure in setting "
+                                                                              "up encrypted transport: %s",
+                                                                              nt_errstr(status));
+                                               exit_server_cleanly(reason);
                                        }
                                }
                                return;
@@ -3702,7 +3706,7 @@ cap_low = 0x%x, cap_high = 0x%x\n",
                                if ((get_current_uid(conn) != 0) || !CAN_WRITE(conn)) {
                                        DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
                                                 lp_servicename(SNUM(conn)),
-                                                conn->session_info->unix_name));
+                                                conn->session_info->unix_info->unix_name));
                                        reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                                        return;
                                }
@@ -4670,8 +4674,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                 */
                case SMB_QUERY_FILE_STREAM_INFO:
                case SMB_FILE_STREAM_INFORMATION: {
-                       unsigned int num_streams;
-                       struct stream_struct *streams;
+                       unsigned int num_streams = 0;
+                       struct stream_struct *streams = NULL;
 
                        DEBUG(10,("smbd_do_qfilepathinfo: "
                                  "SMB_FILE_STREAM_INFORMATION\n"));
@@ -4680,9 +4684,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                                return NT_STATUS_INVALID_PARAMETER;
                        }
 
-                       status = SMB_VFS_STREAMINFO(
-                               conn, fsp, smb_fname->base_name, talloc_tos(),
-                               &num_streams, &streams);
+                       status = vfs_streaminfo(conn, fsp, smb_fname->base_name,
+                                               talloc_tos(), &num_streams, &streams);
 
                        if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(10, ("could not get stream info: %s\n",
@@ -4767,7 +4770,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                case SMB_QUERY_FILE_UNIX_LINK:
                        {
                                int len;
-                               char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1);
+                               char *buffer = talloc_array(mem_ctx, char, PATH_MAX+1);
 
                                if (!buffer) {
                                        return NT_STATUS_NO_MEMORY;
@@ -5101,6 +5104,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
        } else {
                uint32_t name_hash;
                char *fname = NULL;
+               uint32_t ucf_flags = 0;
 
                /* qpathinfo */
                if (total_params < 7) {
@@ -5112,9 +5116,16 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
 
                DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
 
-               if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
-                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                       return;
+               if (INFO_LEVEL_IS_UNIX(info_level)) {
+                       if (!lp_unix_extensions()) {
+                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+                               return;
+                       }
+                       if (info_level == SMB_QUERY_FILE_UNIX_BASIC ||
+                                       info_level == SMB_QUERY_FILE_UNIX_INFO2 ||
+                                       info_level == SMB_QUERY_FILE_UNIX_LINK) {
+                               ucf_flags |= UCF_UNIX_NAME_LOOKUP;
+                       }
                }
 
                srvstr_get_path(req, params, req->flags2, &fname, &params[6],
@@ -5129,7 +5140,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
                                        conn,
                                        req->flags2 & FLAGS2_DFS_PATHNAMES,
                                        fname,
-                                       0,
+                                       ucf_flags,
                                        NULL,
                                        &smb_fname);
                if (!NT_STATUS_IS_OK(status)) {
@@ -5300,7 +5311,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        }
 
                        /* Copy the lock range data. */
-                       lock_data = (char *)TALLOC_MEMDUP(
+                       lock_data = (char *)talloc_memdup(
                                req, pdata, total_data);
                        if (!lock_data) {
                                reply_nterror(req, NT_STATUS_NO_MEMORY);
@@ -5762,7 +5773,7 @@ static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (fsp && !(fsp->access_mask & FILE_WRITE_EA)) {
+       if (!(fsp->access_mask & FILE_WRITE_EA)) {
                return NT_STATUS_ACCESS_DENIED;
        }
 
@@ -5816,7 +5827,7 @@ static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
 
        /* The set is across all open files on this dev/inode pair. */
        if (!set_delete_on_close(fsp, delete_on_close,
-                                &conn->session_info->utok)) {
+                                conn->session_info->unix_token)) {
                return NT_STATUS_ACCESS_DENIED;
        }
        return NT_STATUS_OK;
@@ -6049,8 +6060,9 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn,
                  "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
                  fsp->fnum, fsp_str_dbg(fsp),
                  smb_fname_str_dbg(smb_fname_dst)));
-       status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
-                                     overwrite);
+       status = rename_internals_fsp(conn, fsp, smb_fname_dst,
+                               (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
+                               overwrite);
 
  out:
        TALLOC_FREE(smb_fname_dst);
@@ -6552,10 +6564,6 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (fsp && !(fsp->access_mask & FILE_WRITE_ATTRIBUTES)) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        /* create time */
        ft.create_time = convert_time_t_to_timespec(srv_make_unix_date2(pdata));
        /* access time */
@@ -6614,16 +6622,16 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
                allocation_size = smb_roundup(conn, allocation_size);
        }
 
-       if (fsp && !(fsp->access_mask & FILE_WRITE_DATA)) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
                  "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname),
                  (double)allocation_size));
 
        if (fsp && fsp->fh->fd != -1) {
                /* Open file handle. */
+               if (!(fsp->access_mask & FILE_WRITE_DATA)) {
+                       return NT_STATUS_ACCESS_DENIED;
+               }
+
                /* Only change if needed. */
                if (allocation_size != get_file_size_stat(&smb_fname->st)) {
                        if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
@@ -6715,10 +6723,6 @@ static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
                  "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
                  (double)size));
 
-       if (fsp && !(fsp->access_mask & FILE_WRITE_DATA)) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        return smb_set_file_size(conn, req,
                                fsp,
                                smb_fname,
@@ -7225,6 +7229,9 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
  Open/Create a file with POSIX semantics.
 ****************************************************************************/
 
+#define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
+#define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
+
 static NTSTATUS smb_posix_open(connection_struct *conn,
                               struct smb_request *req,
                                char **ppdata,
@@ -7270,13 +7277,14 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
 
        switch (wire_open_mode & SMB_ACCMODE) {
                case SMB_O_RDONLY:
-                       access_mask = FILE_READ_DATA;
+                       access_mask = SMB_O_RDONLY_MAPPING;
                        break;
                case SMB_O_WRONLY:
-                       access_mask = FILE_WRITE_DATA;
+                       access_mask = SMB_O_WRONLY_MAPPING;
                        break;
                case SMB_O_RDWR:
-                       access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
+                       access_mask = (SMB_O_RDONLY_MAPPING|
+                                       SMB_O_WRONLY_MAPPING);
                        break;
                default:
                        DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
@@ -7354,20 +7362,21 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
        if (wire_open_mode & SMB_O_SYNC) {
                create_options |= FILE_WRITE_THROUGH;
        }
+       if (wire_open_mode & SMB_O_APPEND) {
+               access_mask |= FILE_APPEND_DATA;
+       }
+       if (wire_open_mode & SMB_O_DIRECT) {
+               mod_unixmode |= FILE_FLAG_NO_BUFFERING;
+       }
+
        if ((wire_open_mode & SMB_O_DIRECTORY) ||
                        VALID_STAT_OF_DIR(smb_fname->st)) {
-               if (access_mask != FILE_READ_DATA) {
+               if (access_mask != SMB_O_RDONLY_MAPPING) {
                        return NT_STATUS_FILE_IS_A_DIRECTORY;
                }
                create_options &= ~FILE_NON_DIRECTORY_FILE;
                create_options |= FILE_DIRECTORY_FILE;
        }
-       if (wire_open_mode & SMB_O_APPEND) {
-               access_mask |= FILE_APPEND_DATA;
-       }
-       if (wire_open_mode & SMB_O_DIRECT) {
-               mod_unixmode |= FILE_FLAG_NO_BUFFERING;
-       }
 
        DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
                smb_fname_str_dbg(smb_fname),
@@ -8040,7 +8049,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                                         ppdata, total_data,
                                         &data_return_size);
        if (!NT_STATUS_IS_OK(status)) {
-               if (open_was_deferred(req->mid)) {
+               if (open_was_deferred(req->sconn, req->mid)) {
                        /* We have re-scheduled this call. */
                        return;
                }
@@ -8321,7 +8330,7 @@ static void call_trans2getdfsreferral(connection_struct *conn,
                return;
        }
 
-       SSVAL(req->inbuf, smb_flg2,
+       SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
              SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
        send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
 
@@ -8370,7 +8379,7 @@ static void call_trans2ioctl(connection_struct *conn,
                        SSVAL(pdata, 0, 0);
                }
                srvstr_push(pdata, req->flags2, pdata + 2,
-                           global_myname(), 15,
+                           lp_netbios_name(), 15,
                            STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
                srvstr_push(pdata, req->flags2, pdata+18,
                            lp_servicename(SNUM(conn)), 13,
@@ -8452,7 +8461,7 @@ static void handle_trans2(connection_struct *conn, struct smb_request *req,
 {
        if (get_Protocol() >= PROTOCOL_NT1) {
                req->flags2 |= 0x40; /* IS_LONG_NAME */
-               SSVAL(req->inbuf,smb_flg2,req->flags2);
+               SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
        }
 
        if (conn->encrypt_level == Required && !req->encrypted) {
@@ -8665,7 +8674,7 @@ void reply_trans2(struct smb_request *req)
                }
        }
 
-       if ((state = TALLOC_P(conn, struct trans_state)) == NULL) {
+       if ((state = talloc(conn, struct trans_state)) == NULL) {
                DEBUG(0, ("talloc failed\n"));
                reply_nterror(req, NT_STATUS_NO_MEMORY);
                END_PROFILE(SMBtrans2);
@@ -8811,7 +8820,7 @@ void reply_transs2(struct smb_request *req)
 
        START_PROFILE(SMBtranss2);
 
-       show_msg((char *)req->inbuf);
+       show_msg((const char *)req->inbuf);
 
        if (req->wct < 8) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);