[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Fri May 9 17:38:03 MDT 2014


The branch, master has been updated
       via  cf75ef9 pidl/lib/wscript_build: make use of PERL_LIB_INSTALL_DIR
       via  d18ee9e script/autobuild: make use of --with-perl-{arch,lib}-install-dir
       via  2637890 wafsamba: Fail with error message if perl doesn't provide valid dirs.
       via  b2ce244 s3: libsmbclient: Work around bugs in SLES cifsd and Apple smbx SMB1 servers.
       via  3d8ba9b s3: client : correctly fill in the struct smb_create_returns from cli_ntcreate(), cli_ntcreate_recv(), cli_nttrans_create() and cli_nttrans_create_recv().
       via  69e24b4 s3: client : Add extra return parameter to all client open calls.
       via  2900dfa s3: client - rename 'struct smb2_create_returns' to 'struct smb_create_returns' so we can use this in SMB1 create returns as well.
      from  4bc9bbe selftest: skip GETADDRINFO tests

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit cf75ef9f73f2cdbf2a039bbc9468f5da6a14834e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri May 9 11:49:10 2014 +0200

    pidl/lib/wscript_build: make use of PERL_LIB_INSTALL_DIR
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10472
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Sat May 10 01:37:33 CEST 2014 on sn-devel-104

commit d18ee9e4b6f4c9a24b555c111e08396012c1755a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri May 9 11:48:26 2014 +0200

    script/autobuild: make use of --with-perl-{arch,lib}-install-dir
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10472
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 2637890ef42a238093f0f3cbdda0d621d5f9b2e2
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri May 9 09:42:23 2014 +0200

    wafsamba: Fail with error message if perl doesn't provide valid dirs.
    
    We try harder to get valid directories, we now fallback like this:
    
    vendorarch => sitearch => archlib
    and
    vendorlib => sitelib => privlib
    
    The new options are --with-perl-arch-install-dir and
    --with-perl-lib-install-dir.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10472
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit b2ce2441a35ed68c39791168217d159352b5143c
Author: Jeremy Allison <jra at samba.org>
Date:   Thu May 8 21:31:49 2014 -0700

    s3: libsmbclient: Work around bugs in SLES cifsd and Apple smbx SMB1 servers.
    
    SLES's cifsd and Apple's smbx do not correctly handle FILE_NON_DIRECTORY_FILE
    which prevents recursive copies in gvfs from working correctly [1] since GVFS
    tries to open the directory, expecting ENOTDIR, but it suceeds and appears as a
    zero byte file.
    
    This fix adds code to the cli_open() open code that checks if
    CreateOptions was requested with FILE_NON_DIRECTORY_FILE set,
    and if the attributes returned include FILE_ATTRIBUTE_DIRECTORY
    we synchronously close the file handle just opened, and return
    NT_STATUS_FILE_IS_A_DIRECTORY to the caller.
    
    Depends on the previous API update to cli_ntcreate()
    to add returned attributes.
    
    Fixes bug #10587 - Opening directories on SLES's cifsd and Apple's smbx succeeds.
    
    https://bugzilla.samba.org/show_bug.cgi?id=10587
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 3d8ba9b34e34c1f3e0c1c231d6b772994b45eeaf
Author: Jeremy Allison <jra at samba.org>
Date:   Thu May 8 21:23:22 2014 -0700

    s3: client : correctly fill in the struct smb_create_returns from cli_ntcreate(), cli_ntcreate_recv(), cli_nttrans_create() and cli_nttrans_create_recv().
    
    This completes the update of the create API to return
    all the data returned by the server on open.
    
    We can now use this data to detect buggy servers
    without an extra round trip.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 69e24b4e8bc607806453ab137efda6d6bf74fb12
Author: Jeremy Allison <jra at samba.org>
Date:   Thu May 8 20:55:57 2014 -0700

    s3: client : Add extra return parameter to all client open calls.
    
    Add a return parameter of struct smb_create_returns *cr to
    cli_ntcreate()
    cli_ntcreate_recv()
    cli_nttrans_create()
    cli_nttrans_create_recv()
    
    Always pass in NULL for now. This fixes the create
    API to always fully return the data the server has
    given back to us on the open file to the caller.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 2900dfa5b928ef237e72ac4e15481e083d61750a
Author: Jeremy Allison <jra at samba.org>
Date:   Thu May 8 20:08:41 2014 -0700

    s3: client - rename 'struct smb2_create_returns' to 'struct smb_create_returns' so we can use this in SMB1 create returns as well.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

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

Summary of changes:
 buildtools/wafadmin/Tools/perl.py     |   58 ++++++++++-----
 libcli/smb/smb2_create_blob.h         |    2 +-
 libcli/smb/smb2cli_create.c           |    6 +-
 libcli/smb/smbXcli_base.h             |    6 +-
 pidl/lib/wscript_build                |    4 +-
 script/autobuild.py                   |    4 +-
 source3/client/client.c               |   10 ++--
 source3/libsmb/cli_smb2_fnum.c        |    4 +-
 source3/libsmb/cli_smb2_fnum.h        |    2 +-
 source3/libsmb/clifile.c              |   73 +++++++++++++++++---
 source3/libsmb/cliquota.c             |    2 +-
 source3/libsmb/clisymlink.c           |    4 +-
 source3/libsmb/libsmb_xattr.c         |    6 +-
 source3/libsmb/proto.h                |   14 +++-
 source3/libsmb/pylibsmb.c             |    2 +-
 source3/torture/nbench.c              |    2 +-
 source3/torture/nbio.c                |    2 +-
 source3/torture/test_chain3.c         |    2 +-
 source3/torture/test_cleanup.c        |   14 ++--
 source3/torture/test_notify.c         |    6 +-
 source3/torture/test_notify_online.c  |    4 +-
 source3/torture/test_nttrans_create.c |    4 +-
 source3/torture/test_nttrans_fsctl.c  |    2 +-
 source3/torture/test_posix_append.c   |    2 +-
 source3/torture/torture.c             |  125 +++++++++++++++++----------------
 source3/torture/utable.c              |    2 +-
 source3/utils/net_rpc.c               |    3 +-
 source3/utils/net_rpc_printer.c       |    7 +-
 source3/utils/smbcacls.c              |    6 +-
 29 files changed, 233 insertions(+), 145 deletions(-)


Changeset truncated at 500 lines:

diff --git a/buildtools/wafadmin/Tools/perl.py b/buildtools/wafadmin/Tools/perl.py
index e65ee5c..0f34e79 100644
--- a/buildtools/wafadmin/Tools/perl.py
+++ b/buildtools/wafadmin/Tools/perl.py
@@ -98,33 +98,53 @@ def check_perl_ext_devel(conf):
 	conf.env.EXTUTILS_TYPEMAP  = read_out('print "$Config{privlib}/ExtUtils/typemap"')
 	conf.env.perlext_PATTERN   = '%s.' + read_out('print $Config{dlext}')[0]
 
-	if getattr(Options.options, 'perl_vendorarch_dir', None):
-		conf.env.PERL_VENDORARCH_DIR = Options.options.perl_vendorarch_dir
-	else:
-		try:
-			conf.env.PERL_VENDORARCH_DIR = read_out('print $Config{vendorarch}')[0]
-		except IndexError:
-			conf.env.PERL_VENDORARCH_DIR = "${DATADIR}/perl5"
-
-	if getattr(Options.options, 'perl_vendorlib_dir', None):
-		conf.env.PERL_VENDORLIB_DIR = Options.options.perl_vendorlib_dir
-	else:
-		try:
-			conf.env.PERL_VENDORLIB_DIR = read_out('print $Config{vendorlib}')[0]
-		except IndexError:
-			conf.env.PERL_VENDORLIB_DIR = "${LIBDIR}/perl5"
+	def try_any(keys):
+		for k in keys:
+			conf.start_msg("Checking for perl $Config{%s}:" % k)
+			try:
+				v = read_out('print $Config{%s}' % k)[0]
+				conf.end_msg("'%s'" % (v), 'GREEN')
+				return v
+			except IndexError:
+				conf.end_msg(False, 'YELLOW')
+				pass
+		return None
+
+	perl_arch_install_dir = None
+	if getattr(Options.options, 'perl_arch_install_dir', None):
+		perl_arch_install_dir = Options.options.perl_arch_install_dir
+	if perl_arch_install_dir is None:
+		perl_arch_install_dir = try_any(['vendorarch', 'sitearch', 'archlib'])
+	if perl_arch_install_dir is None:
+		conf.fatal('No perl arch install directory autodetected.' +
+			   'Please define it with --with-perl-arch-install-dir.')
+	conf.start_msg("PERL_ARCH_INSTALL_DIR: ")
+	conf.end_msg("'%s'" % (perl_arch_install_dir), 'GREEN')
+	conf.env.PERL_ARCH_INSTALL_DIR = perl_arch_install_dir
+
+	perl_lib_install_dir = None
+	if getattr(Options.options, 'perl_lib_install_dir', None):
+		perl_lib_install_dir = Options.options.perl_lib_install_dir
+	if perl_lib_install_dir is None:
+		perl_lib_install_dir = try_any(['vendorlib', 'sitelib', 'privlib'])
+	if perl_lib_install_dir is None:
+		conf.fatal('No perl lib install directory autodetected. ' +
+			   'Please define it with --with-perl-lib-install-dir.')
+	conf.start_msg("PERL_LIB_INSTALL_DIR: ")
+	conf.end_msg("'%s'" % (perl_lib_install_dir), 'GREEN')
+	conf.env.PERL_LIB_INSTALL_DIR = perl_lib_install_dir
 
 def set_options(opt):
 	opt.add_option("--with-perl-binary", type="string", dest="perlbinary", help = 'Specify alternate perl binary', default=None)
 
-	opt.add_option("--with-perl-vendorarch",
+	opt.add_option("--with-perl-arch-install-dir",
 		       type="string",
-		       dest="perl_vendorarch_dir",
+		       dest="perl_arch_install_dir",
 		       help = ('Specify directory where to install arch specific files'),
 		       default=None)
 
-	opt.add_option("--with-perl-vendorlib",
+	opt.add_option("--with-perl-lib-install-dir",
 		       type="string",
-		       dest="perl_vendorlib_dir",
+		       dest="perl_lib_install_dir",
 		       help = ('Specify directory where to install vendor specific files'),
 		       default=None)
diff --git a/libcli/smb/smb2_create_blob.h b/libcli/smb/smb2_create_blob.h
index 2f915b3..90697a7 100644
--- a/libcli/smb/smb2_create_blob.h
+++ b/libcli/smb/smb2_create_blob.h
@@ -33,7 +33,7 @@ struct smb2_create_blobs {
 	struct smb2_create_blob *blobs;
 };
 
-struct smb2_create_returns {
+struct smb_create_returns {
 	uint8_t oplock_level;
 	uint32_t create_action;
 	NTTIME creation_time;
diff --git a/libcli/smb/smb2cli_create.c b/libcli/smb/smb2cli_create.c
index 9cb94b1..834a881 100644
--- a/libcli/smb/smb2cli_create.c
+++ b/libcli/smb/smb2cli_create.c
@@ -29,7 +29,7 @@ struct smb2cli_create_state {
 
 	uint64_t fid_persistent;
 	uint64_t fid_volatile;
-	struct smb2_create_returns cr;
+	struct smb_create_returns cr;
 	struct smb2_create_blobs blobs;
 };
 
@@ -225,7 +225,7 @@ static void smb2cli_create_done(struct tevent_req *subreq)
 NTSTATUS smb2cli_create_recv(struct tevent_req *req,
 			     uint64_t *fid_persistent,
 			     uint64_t *fid_volatile,
-			     struct smb2_create_returns *cr)
+			     struct smb_create_returns *cr)
 {
 	struct smb2cli_create_state *state =
 		tevent_req_data(req,
@@ -258,7 +258,7 @@ NTSTATUS smb2cli_create(struct smbXcli_conn *conn,
 			struct smb2_create_blobs *blobs,
 			uint64_t *fid_persistent,
 			uint64_t *fid_volatile,
-			struct smb2_create_returns *cr)
+			struct smb_create_returns *cr)
 {
 	TALLOC_CTX *frame = talloc_stackframe();
 	struct tevent_context *ev;
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 888242b..8cde85e 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -28,7 +28,7 @@ struct smb_trans_enc_state;
 struct GUID;
 struct iovec;
 struct smb2_create_blobs;
-struct smb2_create_returns;
+struct smb_create_returns;
 
 struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx,
 					 int fd,
@@ -461,7 +461,7 @@ struct tevent_req *smb2cli_create_send(
 NTSTATUS smb2cli_create_recv(struct tevent_req *req,
 			     uint64_t *fid_persistent,
 			     uint64_t *fid_volatile,
-			     struct smb2_create_returns *cr);
+			     struct smb_create_returns *cr);
 NTSTATUS smb2cli_create(struct smbXcli_conn *conn,
 			uint32_t timeout_msec,
 			struct smbXcli_session *session,
@@ -477,7 +477,7 @@ NTSTATUS smb2cli_create(struct smbXcli_conn *conn,
 			struct smb2_create_blobs *blobs,
 			uint64_t *fid_persistent,
 			uint64_t *fid_volatile,
-			struct smb2_create_returns *cr);
+			struct smb_create_returns *cr);
 
 struct tevent_req *smb2cli_close_send(TALLOC_CTX *mem_ctx,
 				      struct tevent_context *ev,
diff --git a/pidl/lib/wscript_build b/pidl/lib/wscript_build
index 5023e07..54b3170 100644
--- a/pidl/lib/wscript_build
+++ b/pidl/lib/wscript_build
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 # install the pidl modules
-bld.INSTALL_FILES(bld.env.PERL_VENDORLIB_DIR,
+bld.INSTALL_FILES(bld.env.PERL_LIB_INSTALL_DIR,
                   '''
                   Parse/Pidl.pm
                   Parse/Pidl/Samba4.pm
@@ -32,6 +32,6 @@ bld.INSTALL_FILES(bld.env.PERL_VENDORLIB_DIR,
                   flat=False)
 
 if not bld.CONFIG_SET('USING_SYSTEM_PARSE_YAPP_DRIVER'):
-    bld.INSTALL_FILES(bld.env.PERL_VENDORLIB_DIR,
+    bld.INSTALL_FILES(bld.env.PERL_LIB_INSTALL_DIR,
                       'Parse/Yapp/Driver.pm',
                       flat=False)
diff --git a/script/autobuild.py b/script/autobuild.py
index afd8d3d..3b634e8 100755
--- a/script/autobuild.py
+++ b/script/autobuild.py
@@ -230,7 +230,9 @@ class builder(object):
         self.cmd = self.cmd.replace("${PYTHON_PREFIX}", get_python_lib(standard_lib=1, prefix=self.prefix))
         self.cmd = self.cmd.replace("${PREFIX}", "--prefix=%s" % self.prefix)
         self.cmd = self.cmd.replace("${PREFIX_DIR}", "%s" % self.prefix)
-        self.cmd = self.cmd.replace("${PERL_VENDOR_LIB}", "--with-perl-vendorlib=%s/share/perl5" % self.prefix)
+        perl_vendor_lib = "--with-perl-arch-install-dir=%s/share/perl5 " % self.prefix
+        perl_vendor_lib += "--with-perl-lib-install-dir=%s/lib/perl5" % self.prefix
+        self.cmd = self.cmd.replace("${PERL_VENDOR_LIB}", perl_vendor_lib)
 #        if self.output_mime_type == "text/x-subunit":
 #            self.cmd += " | %s --immediate" % (os.path.join(os.path.dirname(__file__), "selftest/format-subunit"))
         print '%s: [%s] Running %s' % (self.name, self.stage, self.cmd)
diff --git a/source3/client/client.c b/source3/client/client.c
index 9e1f83d..592258d 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -573,7 +573,7 @@ static NTSTATUS display_finfo(struct cli_state *cli_state, struct file_info *fin
 		status = cli_ntcreate(cli_state, afname, 0,
 				      CREATE_ACCESS_READ, 0,
 				      FILE_SHARE_READ|FILE_SHARE_WRITE,
-				      FILE_OPEN, 0x0, 0x0, &fnum);
+				      FILE_OPEN, 0x0, 0x0, &fnum, NULL);
 		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG( 0, ("display_finfo() Failed to open %s: %s\n",
 				   afname, nt_errstr(status)));
@@ -1772,7 +1772,7 @@ static int do_allinfo(const char *name)
 			      SEC_STD_SYNCHRONIZE, 0,
 			      FILE_SHARE_READ|FILE_SHARE_WRITE
 			      |FILE_SHARE_DELETE,
-			      FILE_OPEN, 0x0, 0x0, &fnum);
+			      FILE_OPEN, 0x0, 0x0, &fnum, NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		/*
 		 * Ignore failure, it does not hurt if we can't list
@@ -2496,12 +2496,12 @@ static int cmd_open(void)
 	status = cli_ntcreate(targetcli, targetname, 0,
 			FILE_READ_DATA|FILE_WRITE_DATA, 0,
 			FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN,
-			0x0, 0x0, &fnum);
+			0x0, 0x0, &fnum, NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		status = cli_ntcreate(targetcli, targetname, 0,
 				FILE_READ_DATA, 0,
 				FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN,
-				0x0, 0x0, &fnum);
+				0x0, 0x0, &fnum, NULL);
 		if (NT_STATUS_IS_OK(status)) {
 			d_printf("open file %s: for read/write fnum %d\n", targetname, fnum);
 		} else {
@@ -3943,7 +3943,7 @@ static int cmd_notify(void)
 	status = cli_ntcreate(
 		cli, name, 0, FILE_READ_DATA, 0,
 		FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
-		FILE_OPEN, 0, 0, &fnum);
+		FILE_OPEN, 0, 0, &fnum, NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Could not open file: %s\n", nt_errstr(status));
 		goto fail;
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 1e2047e..8eb776a 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -163,7 +163,7 @@ NTSTATUS cli_smb2_create_fnum(struct cli_state *cli,
 			uint32_t create_disposition,
 			uint32_t create_options,
 			uint16_t *pfid,
-			struct smb2_create_returns *cr)
+			struct smb_create_returns *cr)
 {
 	NTSTATUS status;
 	struct smb2_hnd h;
@@ -660,7 +660,7 @@ NTSTATUS cli_smb2_qpathinfo_basic(struct cli_state *cli,
 				uint32_t *attributes)
 {
 	NTSTATUS status;
-	struct smb2_create_returns cr;
+	struct smb_create_returns cr;
 	uint16_t fnum = 0xffff;
 	size_t namelen = strlen(name);
 
diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
index a5cae25..61a0f68 100644
--- a/source3/libsmb/cli_smb2_fnum.h
+++ b/source3/libsmb/cli_smb2_fnum.h
@@ -34,7 +34,7 @@ NTSTATUS cli_smb2_create_fnum(struct cli_state *cli,
 			uint32_t create_disposition,
 			uint32_t create_options,
 			uint16_t *pfid,
-			struct smb2_create_returns *cr);
+			struct smb_create_returns *cr);
 
 NTSTATUS cli_smb2_close_fnum(struct cli_state *cli, uint16_t fnum);
 NTSTATUS cli_smb2_mkdir(struct cli_state *cli, const char *dirname);
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 424354b..70b769d 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1795,6 +1795,7 @@ NTSTATUS cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag)
 struct cli_ntcreate_state {
 	uint16_t vwv[24];
 	uint16_t fnum;
+	struct smb_create_returns cr;
 };
 
 static void cli_ntcreate_done(struct tevent_req *subreq);
@@ -1880,17 +1881,29 @@ static void cli_ntcreate_done(struct tevent_req *subreq)
 	uint8_t *bytes;
 	NTSTATUS status;
 
-	status = cli_smb_recv(subreq, state, NULL, 3, &wct, &vwv,
+	status = cli_smb_recv(subreq, state, NULL, 34, &wct, &vwv,
 			      &num_bytes, &bytes);
 	TALLOC_FREE(subreq);
 	if (tevent_req_nterror(req, status)) {
 		return;
 	}
+	state->cr.oplock_level = CVAL(vwv+2, 0);
 	state->fnum = SVAL(vwv+2, 1);
+	state->cr.create_action = IVAL(vwv+3, 1);
+	state->cr.creation_time = BVAL(vwv+5, 1);
+	state->cr.last_access_time = BVAL(vwv+9, 1);
+	state->cr.last_write_time = BVAL(vwv+13, 1);
+	state->cr.change_time   = BVAL(vwv+17, 1);
+	state->cr.file_attributes = IVAL(vwv+21, 1);
+	state->cr.allocation_size = BVAL(vwv+23, 1);
+	state->cr.end_of_file   = BVAL(vwv+27, 1);
+
 	tevent_req_done(req);
 }
 
-NTSTATUS cli_ntcreate_recv(struct tevent_req *req, uint16_t *pfnum)
+NTSTATUS cli_ntcreate_recv(struct tevent_req *req,
+		uint16_t *pfnum,
+		struct smb_create_returns *cr)
 {
 	struct cli_ntcreate_state *state = tevent_req_data(
 		req, struct cli_ntcreate_state);
@@ -1900,6 +1913,9 @@ NTSTATUS cli_ntcreate_recv(struct tevent_req *req, uint16_t *pfnum)
 		return status;
 	}
 	*pfnum = state->fnum;
+	if (cr != NULL) {
+		*cr = state->cr;
+	}
 	return NT_STATUS_OK;
 }
 
@@ -1912,7 +1928,8 @@ NTSTATUS cli_ntcreate(struct cli_state *cli,
 		      uint32_t CreateDisposition,
 		      uint32_t CreateOptions,
 		      uint8_t SecurityFlags,
-		      uint16_t *pfid)
+		      uint16_t *pfid,
+		      struct smb_create_returns *cr)
 {
 	TALLOC_CTX *frame = NULL;
 	struct tevent_context *ev;
@@ -1929,7 +1946,7 @@ NTSTATUS cli_ntcreate(struct cli_state *cli,
 					CreateDisposition,
 					CreateOptions,
 					pfid,
-					NULL);
+					cr);
 	}
 
 	frame = talloc_stackframe();
@@ -1962,7 +1979,7 @@ NTSTATUS cli_ntcreate(struct cli_state *cli,
 		goto fail;
 	}
 
-	status = cli_ntcreate_recv(req, pfid);
+	status = cli_ntcreate_recv(req, pfid, cr);
  fail:
 	TALLOC_FREE(frame);
 	return status;
@@ -1970,6 +1987,7 @@ NTSTATUS cli_ntcreate(struct cli_state *cli,
 
 struct cli_nttrans_create_state {
 	uint16_t fnum;
+	struct smb_create_returns cr;
 };
 
 static void cli_nttrans_create_done(struct tevent_req *subreq);
@@ -2082,12 +2100,24 @@ static void cli_nttrans_create_done(struct tevent_req *subreq)
 	if (tevent_req_nterror(req, status)) {
 		return;
 	}
+	state->cr.oplock_level = CVAL(param, 0);
 	state->fnum = SVAL(param, 2);
+	state->cr.create_action = IVAL(param, 4);
+	state->cr.creation_time = BVAL(param, 12);
+	state->cr.last_access_time = BVAL(param, 20);
+	state->cr.last_write_time = BVAL(param, 28);
+	state->cr.change_time   = BVAL(param, 36);
+	state->cr.file_attributes = IVAL(param, 44);
+	state->cr.allocation_size = BVAL(param, 48);
+	state->cr.end_of_file   = BVAL(param, 56);
+
 	TALLOC_FREE(param);
 	tevent_req_done(req);
 }
 
-NTSTATUS cli_nttrans_create_recv(struct tevent_req *req, uint16_t *fnum)
+NTSTATUS cli_nttrans_create_recv(struct tevent_req *req,
+			uint16_t *fnum,
+			struct smb_create_returns *cr)
 {
 	struct cli_nttrans_create_state *state = tevent_req_data(
 		req, struct cli_nttrans_create_state);
@@ -2097,6 +2127,9 @@ NTSTATUS cli_nttrans_create_recv(struct tevent_req *req, uint16_t *fnum)
 		return status;
 	}
 	*fnum = state->fnum;
+	if (cr != NULL) {
+		*cr = state->cr;
+	}
 	return NT_STATUS_OK;
 }
 
@@ -2112,7 +2145,8 @@ NTSTATUS cli_nttrans_create(struct cli_state *cli,
 			    struct security_descriptor *secdesc,
 			    struct ea_struct *eas,
 			    int num_eas,
-			    uint16_t *pfid)
+			    uint16_t *pfid,
+			    struct smb_create_returns *cr)
 {
 	TALLOC_CTX *frame = talloc_stackframe();
 	struct tevent_context *ev;
@@ -2141,7 +2175,7 @@ NTSTATUS cli_nttrans_create(struct cli_state *cli,
 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
 		goto fail;
 	}
-	status = cli_nttrans_create_recv(req, pfid);
+	status = cli_nttrans_create_recv(req, pfid, cr);
  fail:
 	TALLOC_FREE(frame);
 	return status;
@@ -2353,6 +2387,7 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags,
 	unsigned int openfn = 0;
 	unsigned int dos_deny = 0;
 	uint32_t access_mask, share_mode, create_disposition, create_options;
+	struct smb_create_returns cr;
 
 	/* Do the initial mapping into OpenX parameters. */
 	if (flags & O_CREAT) {
@@ -2433,7 +2468,8 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags,
 				create_disposition,
 				create_options,
 				0,
-				pfnum);
+				pfnum,
+				&cr);
 
 	/* Try and cope will all varients of "we don't do this call"
 	   and fall back to openX. */
@@ -2450,6 +2486,25 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags,
 		goto try_openx;
 	}
 
+	if (NT_STATUS_IS_OK(status) &&
+	    (create_options & FILE_NON_DIRECTORY_FILE) &&
+	    (cr.file_attributes & FILE_ATTRIBUTE_DIRECTORY))
+	{
+		/*
+		 * Some (broken) servers return a valid handle
+		 * for directories even if FILE_NON_DIRECTORY_FILE
+		 * is set. Just close the handle and set the
+		 * error explicitly to NT_STATUS_FILE_IS_A_DIRECTORY.
+		 */
+		status = cli_close(cli, *pfnum);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+		status = NT_STATUS_FILE_IS_A_DIRECTORY;
+		/* Set this so libsmbclient can retrieve it. */
+		cli->raw_status = status;
+	}
+
 	return status;
 
   try_openx:
diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c
index 9136506..21dc72e 100644
--- a/source3/libsmb/cliquota.c
+++ b/source3/libsmb/cliquota.c
@@ -29,7 +29,7 @@ NTSTATUS cli_get_quota_handle(struct cli_state *cli, uint16_t *quota_fnum)
 	return cli_ntcreate(cli, FAKE_FILE_NAME_QUOTA_WIN32,
 		 0x00000016, DESIRED_ACCESS_PIPE,
 		 0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE,
-		 FILE_OPEN, 0x00000000, 0x03, quota_fnum);
+		 FILE_OPEN, 0x00000000, 0x03, quota_fnum, NULL);
 }
 
 void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list)
diff --git a/source3/libsmb/clisymlink.c b/source3/libsmb/clisymlink.c
index 338f932..eacae85 100644
--- a/source3/libsmb/clisymlink.c
+++ b/source3/libsmb/clisymlink.c
@@ -90,7 +90,7 @@ static void cli_symlink_create_done(struct tevent_req *subreq)
 	size_t data_len;
 	NTSTATUS status;
 
-	status = cli_ntcreate_recv(subreq, &state->fnum);
+	status = cli_ntcreate_recv(subreq, &state->fnum, NULL);
 	TALLOC_FREE(subreq);
 	if (tevent_req_nterror(req, status)) {
 		return;
@@ -275,7 +275,7 @@ static void cli_readlink_opened(struct tevent_req *subreq)
 		req, struct cli_readlink_state);
 	NTSTATUS status;
 
-	status = cli_ntcreate_recv(subreq, &state->fnum);
+	status = cli_ntcreate_recv(subreq, &state->fnum, NULL);
 	TALLOC_FREE(subreq);
 	if (tevent_req_nterror(req, status)) {
 		return;
diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c
index 7d34290..8e6590a 100644
--- a/source3/libsmb/libsmb_xattr.c
+++ b/source3/libsmb/libsmb_xattr.c
@@ -904,7 +904,7 @@ cacl_get(SMBCCTX *context,
 		status = cli_ntcreate(targetcli, targetpath, 0,
 				      CREATE_ACCESS_READ, 0,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list