[MAC Lion] smbclient "Open AndX Request->STATUS_NOT_SUPPORTED"
Volker Lendecke
Volker.Lendecke at SerNet.DE
Fri Jul 29 08:45:30 MDT 2011
On Fri, Jul 29, 2011 at 01:51:58AM -0700, okmanoj wrote:
> Dear Volker-Sir,
>
> Thank for your help.
> I can understand, I will discuss with apple support about this and get back.
>
> One more observation windows (at least windows 7) always used ntcreate&x for
> this purpose.
> Do samba has any plan to use ntcreate&x in future releases?
>
> Thank you again for providing you helpful comment.
See the attached patchset that I've just pushed to master.
It will do a fallback to ntcreate&x if the open is replied
to with NT_STATUS_NOT_SUPPORTED.
Volker
--
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
-------------- next part --------------
>From eacbb89fa368a8865334213c80c42c1ec670af4c Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 29 Jul 2011 16:12:16 +0200
Subject: [PATCH 1/4] s3: We only need base_name in map_open_params_to_ntcreate
---
source3/smbd/open.c | 8 ++++----
source3/smbd/proto.h | 2 +-
source3/smbd/reply.c | 8 +++++---
source3/smbd/trans2.c | 3 ++-
4 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index d81c278..8212583 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1339,7 +1339,7 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
Open a file with a share mode - old openX method - map into NTCreate.
****************************************************************************/
-bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
+bool map_open_params_to_ntcreate(const char *smb_base_fname,
int deny_mode, int open_func,
uint32 *paccess_mask,
uint32 *pshare_mode,
@@ -1355,7 +1355,7 @@ bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
"open_func = 0x%x\n",
- smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,
+ smb_base_fname, (unsigned int)deny_mode,
(unsigned int)open_func ));
/* Create the NT compatible access_mask. */
@@ -1430,7 +1430,7 @@ bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
case DENY_DOS:
private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
- if (is_executable(smb_fname->base_name)) {
+ if (is_executable(smb_base_fname)) {
share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
} else {
if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
@@ -1455,7 +1455,7 @@ bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
"share_mode = 0x%x, create_disposition = 0x%x, "
"create_options = 0x%x private_flags = 0x%x\n",
- smb_fname_str_dbg(smb_fname),
+ smb_base_fname,
(unsigned int)access_mask,
(unsigned int)share_mode,
(unsigned int)create_disposition,
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 1f414db..763a946 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -609,7 +609,7 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
uint32 access_mask,
uint32 share_access,
uint32 create_options);
-bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
+bool map_open_params_to_ntcreate(const char *smb_base_fname,
int deny_mode, int open_func,
uint32 *paccess_mask,
uint32 *pshare_mode,
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index e740fb4..59ec8f2 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1789,7 +1789,7 @@ void reply_open(struct smb_request *req)
goto out;
}
- if (!map_open_params_to_ntcreate(smb_fname, deny_mode,
+ if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
OPENX_FILE_EXISTS_OPEN, &access_mask,
&share_mode, &create_disposition,
&create_options, &private_flags)) {
@@ -1964,7 +1964,8 @@ void reply_open_and_X(struct smb_request *req)
goto out;
}
- if (!map_open_params_to_ntcreate(smb_fname, deny_mode, smb_ofun,
+ if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
+ smb_ofun,
&access_mask, &share_mode,
&create_disposition,
&create_options,
@@ -6755,7 +6756,8 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
if (!target_is_directory && count) {
new_create_disposition = FILE_OPEN;
} else {
- if (!map_open_params_to_ntcreate(smb_fname_dst_tmp, 0, ofun,
+ if (!map_open_params_to_ntcreate(smb_fname_dst_tmp->base_name,
+ 0, ofun,
NULL, NULL,
&new_create_disposition,
NULL,
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 90eb40a..859d2ad 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1082,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,
--
1.7.4.1
>From 90a115e037800141c17e9bceb7eebda9e4bce179 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 29 Jul 2011 16:14:39 +0200
Subject: [PATCH 2/4] s3: Make is_executable() available in lib/
---
source3/include/proto.h | 1 +
source3/lib/util.c | 17 +++++++++++++++++
source3/smbd/open.c | 17 -----------------
source3/smbd/proto.h | 1 -
4 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 35c26c2..9eff026 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -606,6 +606,7 @@ bool tevent_req_poll_ntstatus(struct tevent_req *req,
bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result);
int timeval_to_msec(struct timeval t);
char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname);
+bool is_executable(const char *fname);
/* The following definitions come from lib/util_cmdline.c */
diff --git a/source3/lib/util.c b/source3/lib/util.c
index b8fc319..b320931 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -2238,3 +2238,20 @@ char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
return ptr;
}
+
+/*******************************************************************
+ Return True if the filename is one of the special executable types.
+********************************************************************/
+
+bool is_executable(const char *fname)
+{
+ if ((fname = strrchr_m(fname,'.'))) {
+ if (strequal(fname,".com") ||
+ strequal(fname,".dll") ||
+ strequal(fname,".exe") ||
+ strequal(fname,".sym")) {
+ return True;
+ }
+ }
+ return False;
+}
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 8212583..2529cbe 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -698,23 +698,6 @@ static NTSTATUS open_file(files_struct *fsp,
return NT_STATUS_OK;
}
-/*******************************************************************
- Return True if the filename is one of the special executable types.
-********************************************************************/
-
-bool is_executable(const char *fname)
-{
- if ((fname = strrchr_m(fname,'.'))) {
- if (strequal(fname,".com") ||
- strequal(fname,".dll") ||
- strequal(fname,".exe") ||
- strequal(fname,".sym")) {
- return True;
- }
- }
- return False;
-}
-
/****************************************************************************
Check if we can open a file with a share mode.
Returns True if conflict, False if not.
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 763a946..02c82f7 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -589,7 +589,6 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
const char *inherit_from_dir,
const char *fname,
SMB_STRUCT_STAT *psbuf);
-bool is_executable(const char *fname);
bool is_stat_open(uint32 access_mask);
bool request_timed_out(struct timeval request_time,
struct timeval timeout);
--
1.7.4.1
>From b26b2e1e685e6f31f3e91ed1c37994d2b7f01b07 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 29 Jul 2011 16:36:58 +0200
Subject: [PATCH 3/4] s3: Make map_open_params_to_ntcreate() available in lib/
---
source3/include/proto.h | 7 ++
source3/lib/util.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++
source3/smbd/open.c | 147 ----------------------------------------------
source3/smbd/proto.h | 7 --
4 files changed, 155 insertions(+), 154 deletions(-)
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 9eff026..095c52c 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -607,6 +607,13 @@ bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result);
int timeval_to_msec(struct timeval t);
char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname);
bool is_executable(const char *fname);
+bool map_open_params_to_ntcreate(const char *smb_base_fname,
+ int deny_mode, int open_func,
+ uint32 *paccess_mask,
+ uint32 *pshare_mode,
+ uint32 *pcreate_disposition,
+ uint32 *pcreate_options,
+ uint32_t *pprivate_flags);
/* The following definitions come from lib/util_cmdline.c */
diff --git a/source3/lib/util.c b/source3/lib/util.c
index b320931..689d41e 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -29,6 +29,7 @@
#include "../lib/util/util_pw.h"
#include "messages.h"
#include <ccan/hash/hash.h>
+#include "libcli/security/security.h"
/* Max allowable allococation - 256mb - 0x10000000 */
#define MAX_ALLOC_SIZE (1024*1024*256)
@@ -2255,3 +2256,150 @@ bool is_executable(const char *fname)
}
return False;
}
+
+/****************************************************************************
+ Open a file with a share mode - old openX method - map into NTCreate.
+****************************************************************************/
+
+bool map_open_params_to_ntcreate(const char *smb_base_fname,
+ int deny_mode, int open_func,
+ uint32 *paccess_mask,
+ uint32 *pshare_mode,
+ uint32 *pcreate_disposition,
+ uint32 *pcreate_options,
+ uint32_t *pprivate_flags)
+{
+ uint32 access_mask;
+ uint32 share_mode;
+ uint32 create_disposition;
+ uint32 create_options = FILE_NON_DIRECTORY_FILE;
+ uint32_t private_flags = 0;
+
+ DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
+ "open_func = 0x%x\n",
+ smb_base_fname, (unsigned int)deny_mode,
+ (unsigned int)open_func ));
+
+ /* Create the NT compatible access_mask. */
+ switch (GET_OPENX_MODE(deny_mode)) {
+ case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
+ case DOS_OPEN_RDONLY:
+ access_mask = FILE_GENERIC_READ;
+ break;
+ case DOS_OPEN_WRONLY:
+ access_mask = FILE_GENERIC_WRITE;
+ break;
+ case DOS_OPEN_RDWR:
+ case DOS_OPEN_FCB:
+ access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
+ break;
+ default:
+ DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
+ (unsigned int)GET_OPENX_MODE(deny_mode)));
+ return False;
+ }
+
+ /* Create the NT compatible create_disposition. */
+ switch (open_func) {
+ case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
+ create_disposition = FILE_CREATE;
+ break;
+
+ case OPENX_FILE_EXISTS_OPEN:
+ create_disposition = FILE_OPEN;
+ break;
+
+ case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
+ create_disposition = FILE_OPEN_IF;
+ break;
+
+ case OPENX_FILE_EXISTS_TRUNCATE:
+ create_disposition = FILE_OVERWRITE;
+ break;
+
+ case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
+ create_disposition = FILE_OVERWRITE_IF;
+ break;
+
+ default:
+ /* From samba4 - to be confirmed. */
+ if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
+ create_disposition = FILE_CREATE;
+ break;
+ }
+ DEBUG(10,("map_open_params_to_ntcreate: bad "
+ "open_func 0x%x\n", (unsigned int)open_func));
+ return False;
+ }
+
+ /* Create the NT compatible share modes. */
+ switch (GET_DENY_MODE(deny_mode)) {
+ case DENY_ALL:
+ share_mode = FILE_SHARE_NONE;
+ break;
+
+ case DENY_WRITE:
+ share_mode = FILE_SHARE_READ;
+ break;
+
+ case DENY_READ:
+ share_mode = FILE_SHARE_WRITE;
+ break;
+
+ case DENY_NONE:
+ share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
+ break;
+
+ case DENY_DOS:
+ private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
+ if (is_executable(smb_base_fname)) {
+ share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
+ } else {
+ if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
+ share_mode = FILE_SHARE_READ;
+ } else {
+ share_mode = FILE_SHARE_NONE;
+ }
+ }
+ break;
+
+ case DENY_FCB:
+ private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
+ share_mode = FILE_SHARE_NONE;
+ break;
+
+ default:
+ DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
+ (unsigned int)GET_DENY_MODE(deny_mode) ));
+ return False;
+ }
+
+ DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
+ "share_mode = 0x%x, create_disposition = 0x%x, "
+ "create_options = 0x%x private_flags = 0x%x\n",
+ smb_base_fname,
+ (unsigned int)access_mask,
+ (unsigned int)share_mode,
+ (unsigned int)create_disposition,
+ (unsigned int)create_options,
+ (unsigned int)private_flags));
+
+ if (paccess_mask) {
+ *paccess_mask = access_mask;
+ }
+ if (pshare_mode) {
+ *pshare_mode = share_mode;
+ }
+ if (pcreate_disposition) {
+ *pcreate_disposition = create_disposition;
+ }
+ if (pcreate_options) {
+ *pcreate_options = create_options;
+ }
+ if (pprivate_flags) {
+ *pprivate_flags = private_flags;
+ }
+
+ return True;
+
+}
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 2529cbe..510dfe0 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1318,153 +1318,6 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
create_options, fsp_to_dup_into);
}
-/****************************************************************************
- Open a file with a share mode - old openX method - map into NTCreate.
-****************************************************************************/
-
-bool map_open_params_to_ntcreate(const char *smb_base_fname,
- int deny_mode, int open_func,
- uint32 *paccess_mask,
- uint32 *pshare_mode,
- uint32 *pcreate_disposition,
- uint32 *pcreate_options,
- uint32_t *pprivate_flags)
-{
- uint32 access_mask;
- uint32 share_mode;
- uint32 create_disposition;
- uint32 create_options = FILE_NON_DIRECTORY_FILE;
- uint32_t private_flags = 0;
-
- DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
- "open_func = 0x%x\n",
- smb_base_fname, (unsigned int)deny_mode,
- (unsigned int)open_func ));
-
- /* Create the NT compatible access_mask. */
- switch (GET_OPENX_MODE(deny_mode)) {
- case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
- case DOS_OPEN_RDONLY:
- access_mask = FILE_GENERIC_READ;
- break;
- case DOS_OPEN_WRONLY:
- access_mask = FILE_GENERIC_WRITE;
- break;
- case DOS_OPEN_RDWR:
- case DOS_OPEN_FCB:
- access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
- break;
- default:
- DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
- (unsigned int)GET_OPENX_MODE(deny_mode)));
- return False;
- }
-
- /* Create the NT compatible create_disposition. */
- switch (open_func) {
- case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
- create_disposition = FILE_CREATE;
- break;
-
- case OPENX_FILE_EXISTS_OPEN:
- create_disposition = FILE_OPEN;
- break;
-
- case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
- create_disposition = FILE_OPEN_IF;
- break;
-
- case OPENX_FILE_EXISTS_TRUNCATE:
- create_disposition = FILE_OVERWRITE;
- break;
-
- case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
- create_disposition = FILE_OVERWRITE_IF;
- break;
-
- default:
- /* From samba4 - to be confirmed. */
- if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
- create_disposition = FILE_CREATE;
- break;
- }
- DEBUG(10,("map_open_params_to_ntcreate: bad "
- "open_func 0x%x\n", (unsigned int)open_func));
- return False;
- }
-
- /* Create the NT compatible share modes. */
- switch (GET_DENY_MODE(deny_mode)) {
- case DENY_ALL:
- share_mode = FILE_SHARE_NONE;
- break;
-
- case DENY_WRITE:
- share_mode = FILE_SHARE_READ;
- break;
-
- case DENY_READ:
- share_mode = FILE_SHARE_WRITE;
- break;
-
- case DENY_NONE:
- share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
- break;
-
- case DENY_DOS:
- private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
- if (is_executable(smb_base_fname)) {
- share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
- } else {
- if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
- share_mode = FILE_SHARE_READ;
- } else {
- share_mode = FILE_SHARE_NONE;
- }
- }
- break;
-
- case DENY_FCB:
- private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
- share_mode = FILE_SHARE_NONE;
- break;
-
- default:
- DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
- (unsigned int)GET_DENY_MODE(deny_mode) ));
- return False;
- }
-
- DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
- "share_mode = 0x%x, create_disposition = 0x%x, "
- "create_options = 0x%x private_flags = 0x%x\n",
- smb_base_fname,
- (unsigned int)access_mask,
- (unsigned int)share_mode,
- (unsigned int)create_disposition,
- (unsigned int)create_options,
- (unsigned int)private_flags));
-
- if (paccess_mask) {
- *paccess_mask = access_mask;
- }
- if (pshare_mode) {
- *pshare_mode = share_mode;
- }
- if (pcreate_disposition) {
- *pcreate_disposition = create_disposition;
- }
- if (pcreate_options) {
- *pcreate_options = create_options;
- }
- if (pprivate_flags) {
- *pprivate_flags = private_flags;
- }
-
- return True;
-
-}
-
static void schedule_defer_open(struct share_mode_lock *lck,
struct timeval request_time,
struct smb_request *req)
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 02c82f7..b2acaa0 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -608,13 +608,6 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
uint32 access_mask,
uint32 share_access,
uint32 create_options);
-bool map_open_params_to_ntcreate(const char *smb_base_fname,
- int deny_mode, int open_func,
- uint32 *paccess_mask,
- uint32 *pshare_mode,
- uint32 *pcreate_disposition,
- uint32 *pcreate_options,
- uint32_t *pprivate_flags);
void remove_deferred_open_entry(struct file_id id, uint64_t mid,
struct server_id pid);
NTSTATUS open_file_fchmod(connection_struct *conn,
--
1.7.4.1
>From e59f343745c123e5b770a9ce9af094084f373427 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 29 Jul 2011 16:37:18 +0200
Subject: [PATCH 4/4] s3: Add a fallback for missing open&x support in OS/X Lion
---
source3/libsmb/clifile.c | 87 ++++++++++++++++++++++++++++++++++++----------
1 files changed, 68 insertions(+), 19 deletions(-)
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 6503e23..3590350 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -2110,12 +2110,19 @@ NTSTATUS cli_nttrans_create(struct cli_state *cli,
****************************************************************************/
struct cli_open_state {
+ struct tevent_context *ev;
+ struct cli_state *cli;
+ const char *fname;
uint16_t vwv[15];
uint16_t fnum;
+ unsigned openfn;
+ unsigned dos_deny;
+ uint8_t additional_flags;
struct iovec bytes;
};
static void cli_open_done(struct tevent_req *subreq);
+static void cli_open_ntcreate_done(struct tevent_req *subreq);
struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx,
struct event_context *ev,
@@ -2125,64 +2132,61 @@ struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx,
{
struct tevent_req *req, *subreq;
struct cli_open_state *state;
- unsigned openfn;
- unsigned accessmode;
- uint8_t additional_flags;
uint8_t *bytes;
req = tevent_req_create(mem_ctx, &state, struct cli_open_state);
if (req == NULL) {
return NULL;
}
+ state->ev = ev;
+ state->cli = cli;
+ state->fname = fname;
- openfn = 0;
if (flags & O_CREAT) {
- openfn |= (1<<4);
+ state->openfn |= (1<<4);
}
if (!(flags & O_EXCL)) {
if (flags & O_TRUNC)
- openfn |= (1<<1);
+ state->openfn |= (1<<1);
else
- openfn |= (1<<0);
+ state->openfn |= (1<<0);
}
- accessmode = (share_mode<<4);
+ state->dos_deny = (share_mode<<4);
if ((flags & O_ACCMODE) == O_RDWR) {
- accessmode |= 2;
+ state->dos_deny |= 2;
} else if ((flags & O_ACCMODE) == O_WRONLY) {
- accessmode |= 1;
+ state->dos_deny |= 1;
}
#if defined(O_SYNC)
if ((flags & O_SYNC) == O_SYNC) {
- accessmode |= (1<<14);
+ state->dos_deny |= (1<<14);
}
#endif /* O_SYNC */
if (share_mode == DENY_FCB) {
- accessmode = 0xFF;
+ state->dos_deny = 0xFF;
}
SCVAL(state->vwv + 0, 0, 0xFF);
SCVAL(state->vwv + 0, 1, 0);
SSVAL(state->vwv + 1, 0, 0);
SSVAL(state->vwv + 2, 0, 0); /* no additional info */
- SSVAL(state->vwv + 3, 0, accessmode);
+ SSVAL(state->vwv + 3, 0, state->dos_deny);
SSVAL(state->vwv + 4, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
SSVAL(state->vwv + 5, 0, 0);
SIVAL(state->vwv + 6, 0, 0);
- SSVAL(state->vwv + 8, 0, openfn);
+ SSVAL(state->vwv + 8, 0, state->openfn);
SIVAL(state->vwv + 9, 0, 0);
SIVAL(state->vwv + 11, 0, 0);
SIVAL(state->vwv + 13, 0, 0);
- additional_flags = 0;
-
if (cli->use_oplocks) {
/* if using oplocks then ask for a batch oplock via
core and extended methods */
- additional_flags =
+ state->additional_flags =
FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK;
SSVAL(state->vwv+2, 0, SVAL(state->vwv+2, 0) | 6);
}
@@ -2198,7 +2202,8 @@ struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx,
state->bytes.iov_base = (void *)bytes;
state->bytes.iov_len = talloc_get_size(bytes);
- subreq = cli_smb_req_create(state, ev, cli, SMBopenX, additional_flags,
+ subreq = cli_smb_req_create(state, ev, cli, SMBopenX,
+ state->additional_flags,
15, state->vwv, 1, &state->bytes);
if (subreq == NULL) {
TALLOC_FREE(req);
@@ -2239,14 +2244,58 @@ static void cli_open_done(struct tevent_req *subreq)
uint16_t *vwv;
uint8_t *inbuf;
NTSTATUS status;
+ uint32_t access_mask, share_mode, create_disposition, create_options;
status = cli_smb_recv(subreq, state, &inbuf, 3, &wct, &vwv, NULL,
NULL);
TALLOC_FREE(subreq);
+
+ if (NT_STATUS_IS_OK(status)) {
+ state->fnum = SVAL(vwv+2, 0);
+ tevent_req_done(req);
+ }
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+
+ /*
+ * For the new shiny OS/X Lion SMB server, try a ntcreate
+ * fallback.
+ */
+
+ if (!map_open_params_to_ntcreate(state->fname, state->dos_deny,
+ state->openfn, &access_mask,
+ &share_mode, &create_disposition,
+ &create_options, NULL)) {
+ tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+ return;
+ }
+
+ subreq = cli_ntcreate_send(state, state->ev, state->cli,
+ state->fname, 0, access_mask,
+ 0, share_mode, create_disposition,
+ create_options, 0);
+ if (tevent_req_nomem(subreq, req)) {
+ return;
+ }
+ tevent_req_set_callback(subreq, cli_open_ntcreate_done, req);
+}
+
+static void cli_open_ntcreate_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_open_state *state = tevent_req_data(
+ req, struct cli_open_state);
+ NTSTATUS status;
+
+ status = cli_ntcreate_recv(subreq, &state->fnum);
+ TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
}
- state->fnum = SVAL(vwv+2, 0);
tevent_req_done(req);
}
--
1.7.4.1
More information about the samba-technical
mailing list