[SCM] Samba Shared Repository - branch v3-5-test updated
Karolin Seeger
kseeger at samba.org
Thu Aug 18 12:45:53 MDT 2011
The branch, v3-5-test has been updated
via 8e9dfd0 s3: Add a fallback for missing open&x support in OS/X Lion
via aa0c6eb s3: Make map_open_params_to_ntcreate() available in lib/
via 612361b s3: Make is_executable() available in lib/
via 1fa4b36 s3: We only need base_name in map_open_params_to_ntcreate
from 552ccc6 s3/swat: use strlcat instead of strncat to fix build on old Linux distros
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test
- Log -----------------------------------------------------------------
commit 8e9dfd04fac5353fb12270647209ac45d19a1ad2
Author: Volker Lendecke <vl at samba.org>
Date: Fri Jul 29 15:43:46 2011 -0700
s3: Add a fallback for missing open&x support in OS/X Lion
The last 4 patches address bug #8338 (MAC Lion - smbclient "Open AndX
Request->STATUS_NOT_SUPPORTED).
commit aa0c6eb76a6e16652a2ef46560eaffb881792cf6
Author: Volker Lendecke <vl at samba.org>
Date: Fri Jul 29 15:03:03 2011 -0700
s3: Make map_open_params_to_ntcreate() available in lib/
commit 612361bdcaf4256eb54913423e127d0628b35356
Author: Volker Lendecke <vl at samba.org>
Date: Fri Jul 29 14:41:10 2011 -0700
s3: Make is_executable() available in lib/
commit 1fa4b369d2fabbf34cda576d91d8aa9baa4e8b68
Author: Volker Lendecke <vl at samba.org>
Date: Fri Jul 29 14:26:58 2011 -0700
s3: We only need base_name in map_open_params_to_ntcreate
-----------------------------------------------------------------------
Summary of changes:
source3/include/proto.h | 14 ++--
source3/lib/util.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++
source3/libsmb/clifile.c | 91 +++++++++++++++++++++------
source3/smbd/open.c | 158 ----------------------------------------------
source3/smbd/reply.c | 8 ++-
source3/smbd/trans2.c | 3 +-
6 files changed, 243 insertions(+), 189 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d560ee5..c5065e2 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1242,6 +1242,13 @@ const char *strip_hostname(const char *s);
bool tevent_req_poll_ntstatus(struct tevent_req *req,
struct tevent_context *ev,
NTSTATUS *status);
+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);
/* The following definitions come from lib/util_file.c */
@@ -6608,7 +6615,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);
@@ -6628,12 +6634,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 struct smb_filename *smb_fname,
- int deny_mode, int open_func,
- uint32 *paccess_mask,
- uint32 *pshare_mode,
- uint32 *pcreate_disposition,
- uint32 *pcreate_options);
NTSTATUS open_file_fchmod(connection_struct *conn,
struct smb_filename *smb_fname,
files_struct **result);
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 238981d..c7dfa28 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -3075,3 +3075,161 @@ bool tevent_req_poll_ntstatus(struct tevent_req *req,
}
return ret;
}
+
+/*******************************************************************
+ 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;
+}
+
+/****************************************************************************
+ 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 access_mask;
+ uint32 share_mode;
+ uint32 create_disposition;
+ uint32 create_options = FILE_NON_DIRECTORY_FILE;
+
+ 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:
+ create_options |= 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:
+ create_options |= 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\n",
+ smb_base_fname,
+ (unsigned int)access_mask,
+ (unsigned int)share_mode,
+ (unsigned int)create_disposition,
+ (unsigned int)create_options ));
+
+ 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;
+ }
+
+ return True;
+
+}
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 5eb8bd4..9a33db4 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -2149,12 +2149,19 @@ NTSTATUS cli_ntcreate(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,
@@ -2164,64 +2171,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, aSYSTEM | aHIDDEN);
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);
}
@@ -2237,7 +2241,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);
@@ -2278,14 +2283,60 @@ static void cli_open_done(struct tevent_req *subreq)
uint8_t wct;
uint16_t *vwv;
NTSTATUS status;
+ uint32_t access_mask, share_mode, create_disposition, create_options;
status = cli_smb_recv(subreq, 3, &wct, &vwv, NULL, NULL);
+ TALLOC_FREE(subreq);
+
+ if (NT_STATUS_IS_OK(status)) {
+ state->fnum = SVAL(vwv+2, 0);
+ tevent_req_done(req);
+ return;
+ }
+
+ 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)) {
+ 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 (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(subreq);
tevent_req_nterror(req, status);
return;
}
- state->fnum = SVAL(vwv+2, 0);
tevent_req_done(req);
}
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index f0b9271..9048d6b 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -660,23 +660,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.
@@ -1222,147 +1205,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 struct smb_filename *smb_fname,
- int deny_mode, int open_func,
- uint32 *paccess_mask,
- uint32 *pshare_mode,
- uint32 *pcreate_disposition,
- uint32 *pcreate_options)
-{
- uint32 access_mask;
- uint32 share_mode;
- uint32 create_disposition;
- uint32 create_options = FILE_NON_DIRECTORY_FILE;
-
- 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,
- (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;
-
--
Samba Shared Repository
More information about the samba-cvs
mailing list