[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-2005-gbfd1f5d

Stefan Metzmacher metze at samba.org
Wed Jun 3 15:56:29 GMT 2009


The branch, master has been updated
       via  bfd1f5ddc6022960af669f9d9628fee6a2572b00 (commit)
       via  4101f539bf6d6db490c2c259f97157348342f556 (commit)
       via  0ccef51cbeeebd5712f43ed73ee50c25a4fbf84c (commit)
       via  ec0553bb6e66eb2125ae81421285e7ea9fa14e06 (commit)
       via  261c59e3a1ce9edc8c5db74e91a58988ebab6712 (commit)
       via  cfc8d4a1f49a304ab8ff3e1dde7217a031cccf10 (commit)
       via  4b14ebb91d59da2adab85bcba171931395990797 (commit)
       via  0099f4758e88dec5295605498a7387ec5394c8d4 (commit)
       via  076aaf3f4264ca1966a3626c9356ee869c5d4700 (commit)
       via  72f8328820a542167caba198dae23835f3c40a45 (commit)
      from  a02265cdc4ea359979f89af99f58fb0720d7c464 (commit)

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


- Log -----------------------------------------------------------------
commit bfd1f5ddc6022960af669f9d9628fee6a2572b00
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu May 28 01:28:34 2009 +0200

    s3:smbd: implement SMB2 Write
    
    This only works on file shares.
    
    metze

commit 4101f539bf6d6db490c2c259f97157348342f556
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jun 2 12:38:37 2009 +0200

    s3:smbd: implement SMB2 Read
    
    This only works works on file shares.
    
    metze

commit 0ccef51cbeeebd5712f43ed73ee50c25a4fbf84c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jun 2 12:06:34 2009 +0200

    s3:smbd: implement SMB2 Flush
    
    This works only on file shares yet.
    
    metze

commit ec0553bb6e66eb2125ae81421285e7ea9fa14e06
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jun 2 13:42:28 2009 +0200

    s3:smbd: implement SMB2 Close
    
    metze

commit 261c59e3a1ce9edc8c5db74e91a58988ebab6712
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu May 28 00:07:26 2009 +0200

    s3:smbd: implement a simple version of SMB2 Create
    
    It only work on file shares and
    just ignores any additional Create Context Values.
    
    metze

commit cfc8d4a1f49a304ab8ff3e1dde7217a031cccf10
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jun 2 11:54:00 2009 +0200

    s3:smbd: add smbd_smb2_fake_smb_request()
    
    metze

commit 4b14ebb91d59da2adab85bcba171931395990797
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jun 3 11:31:43 2009 +0200

    s3:smbd: return more details in the SMB2 Tree Connect response
    
    metze

commit 0099f4758e88dec5295605498a7387ec5394c8d4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed May 27 18:40:42 2009 +0200

    s3:smbd: create a connection_struct in SMB2 Tree Connect
    
    metze

commit 076aaf3f4264ca1966a3626c9356ee869c5d4700
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed May 27 18:33:45 2009 +0200

    s3:smbd: create a user_struct for compat in SMB2 Session Setup
    
    metze

commit 72f8328820a542167caba198dae23835f3c40a45
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed May 27 18:28:56 2009 +0200

    s3:smbd: add a lazy mode for conn_new() and conn_free() for SMB2
    
    metze

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

Summary of changes:
 source3/Makefile.in           |    7 +-
 source3/smbd/conn.c           |   15 +++
 source3/smbd/globals.h        |   10 ++
 source3/smbd/server.c         |    9 ++
 source3/smbd/smb2_close.c     |  132 ++++++++++++++++++++
 source3/smbd/smb2_create.c    |  274 +++++++++++++++++++++++++++++++++++++++++
 source3/smbd/smb2_flush.c     |  120 ++++++++++++++++++
 source3/smbd/smb2_glue.c      |   51 ++++++++
 source3/smbd/smb2_read.c      |  207 +++++++++++++++++++++++++++++++
 source3/smbd/smb2_server.c    |   12 +-
 source3/smbd/smb2_sesssetup.c |   18 +++-
 source3/smbd/smb2_tcon.c      |   57 ++++++++-
 source3/smbd/smb2_write.c     |  213 ++++++++++++++++++++++++++++++++
 13 files changed, 1111 insertions(+), 14 deletions(-)
 create mode 100644 source3/smbd/smb2_close.c
 create mode 100644 source3/smbd/smb2_create.c
 create mode 100644 source3/smbd/smb2_flush.c
 create mode 100644 source3/smbd/smb2_glue.c
 create mode 100644 source3/smbd/smb2_read.c
 create mode 100644 source3/smbd/smb2_write.c


Changeset truncated at 500 lines:

diff --git a/source3/Makefile.in b/source3/Makefile.in
index e82a0af..689f715 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -751,7 +751,12 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
 	       smbd/file_access.o \
 	       smbd/dnsregister.o smbd/globals.o \
 	       smbd/smb2_server.o smbd/smb2_negprot.o \
-	       smbd/smb2_sesssetup.o smbd/smb2_tcon.o \
+	       smbd/smb2_sesssetup.o smbd/smb2_tcon.o smbd/smb2_glue.o \
+	       smbd/smb2_create.o \
+	       smbd/smb2_close.o \
+	       smbd/smb2_flush.o \
+	       smbd/smb2_read.o \
+	       smbd/smb2_write.o \
 	       smbd/smb2_keepalive.o smbd/smb2_signing.o \
 	       $(MANGLE_OBJ) @VFS_STATIC@
 
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 607329d..af6e091 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -94,6 +94,16 @@ connection_struct *conn_new(struct smbd_server_connection *sconn)
 	int i;
         int find_offset = 1;
 
+	if (sconn->allow_smb2) {
+		if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) ||
+		    !(conn->params = TALLOC_P(conn, struct share_params))) {
+			DEBUG(0,("TALLOC_ZERO() failed!\n"));
+			TALLOC_FREE(conn);
+			return NULL;
+		}
+		return conn;
+	}
+
 find_again:
 	i = bitmap_find(sconn->smb1.tcons.bmap, find_offset);
 	
@@ -286,6 +296,11 @@ void conn_free_internal(connection_struct *conn)
 
 void conn_free(struct smbd_server_connection *sconn, connection_struct *conn)
 {
+	if (sconn->allow_smb2) {
+		conn_free_internal(conn);
+		return;
+	}
+
 	DLIST_REMOVE(sconn->smb1.tcons.Connections, conn);
 
 	bitmap_clear(sconn->smb1.tcons.bmap, conn->cnum);
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 5bd75e7..1c2b628 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -189,11 +189,18 @@ NTSTATUS smbd_smb2_request_done(struct smbd_smb2_request *req,
 NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req);
 
+struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req);
+
 NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_tcon(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_tdis(struct smbd_smb2_request *req);
+NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *req);
+NTSTATUS smbd_smb2_request_process_close(struct smbd_smb2_request *req);
+NTSTATUS smbd_smb2_request_process_flush(struct smbd_smb2_request *req);
+NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req);
+NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_keepalive(struct smbd_smb2_request *req);
 
 struct smbd_smb2_request {
@@ -268,6 +275,8 @@ struct smbd_smb2_session {
 	DATA_BLOB session_key;
 	bool do_signing;
 
+	user_struct *compat_vuser;
+
 	struct {
 		/* an id tree used to allocate tids */
 		struct idr_context *idtree;
@@ -284,6 +293,7 @@ struct smbd_smb2_tcon {
 	struct smbd_smb2_session *session;
 	uint32_t tid;
 	int snum;
+	connection_struct *compat_conn;
 };
 
 struct pending_auth_data;
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 77e487a..a022f3e 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -827,6 +827,15 @@ static void exit_server_common(enum server_exit_reason how,
 	locking_end();
 	printing_end();
 
+	/*
+	 * we need to force the order of freeing the following,
+	 * because smbd_msg_ctx is not a talloc child of smbd_server_conn.
+	 */
+	sconn = NULL;
+	TALLOC_FREE(smbd_server_conn);
+	TALLOC_FREE(smbd_msg_ctx);
+	TALLOC_FREE(smbd_event_ctx);
+
 	if (how != SERVER_EXIT_NORMAL) {
 		int oldlevel = DEBUGLEVEL;
 
diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c
new file mode 100644
index 0000000..a600498
--- /dev/null
+++ b/source3/smbd/smb2_close.c
@@ -0,0 +1,132 @@
+/*
+   Unix SMB/CIFS implementation.
+   Core SMB2 server
+
+   Copyright (C) Stefan Metzmacher 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/globals.h"
+#include "../source4/libcli/smb2/smb2_constants.h"
+
+static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
+				uint16_t in_flags,
+				uint64_t in_file_id_volatile);
+
+NTSTATUS smbd_smb2_request_process_close(struct smbd_smb2_request *req)
+{
+	const uint8_t *inhdr;
+	const uint8_t *inbody;
+	int i = req->current_idx;
+	uint8_t *outhdr;
+	DATA_BLOB outbody;
+	size_t expected_body_size = 0x18;
+	size_t body_size;
+	uint16_t in_flags;
+	uint64_t in_file_id_persistent;
+	uint64_t in_file_id_volatile;
+	NTSTATUS status;
+
+	inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
+	if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
+		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	}
+
+	inbody = (const uint8_t *)req->in.vector[i+1].iov_base;
+
+	body_size = SVAL(inbody, 0x00);
+	if (body_size != expected_body_size) {
+		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	}
+
+	in_flags		= SVAL(inbody, 0x02);
+	in_file_id_persistent	= BVAL(inbody, 0x08);
+	in_file_id_volatile	= BVAL(inbody, 0x10);
+
+	if (in_file_id_persistent != 0) {
+		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
+	}
+
+	status = smbd_smb2_close(req,
+				in_flags,
+				in_file_id_volatile);
+	if (!NT_STATUS_IS_OK(status)) {
+		return smbd_smb2_request_error(req, status);
+	}
+
+	outhdr = (uint8_t *)req->out.vector[i].iov_base;
+
+	outbody = data_blob_talloc(req->out.vector, NULL, 0x3C);
+	if (outbody.data == NULL) {
+		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
+	}
+
+	SSVAL(outbody.data, 0x00, 0x3C);	/* struct size */
+	SSVAL(outbody.data, 0x02, 0);		/* flags */
+	SIVAL(outbody.data, 0x04, 0);		/* reserved */
+	SBVAL(outbody.data, 0x08, 0);		/* creation time */
+	SBVAL(outbody.data, 0x10, 0);		/* last access time */
+	SBVAL(outbody.data, 0x18, 0);		/* last write time */
+	SBVAL(outbody.data, 0x20, 0);		/* change time */
+	SBVAL(outbody.data, 0x28, 0);		/* allocation size */
+	SBVAL(outbody.data, 0x30, 0);		/* end of size */
+	SIVAL(outbody.data, 0x38, 0);		/* file attributes */
+
+	return smbd_smb2_request_done(req, outbody, NULL);
+}
+
+static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
+				uint16_t in_flags,
+				uint64_t in_file_id_volatile)
+{
+	NTSTATUS status;
+	struct smb_request *smbreq;
+	connection_struct *conn = req->tcon->compat_conn;
+	files_struct *fsp;
+
+	DEBUG(10,("smbd_smb2_close: file_id[0x%016llX]\n",
+		  (unsigned long long)in_file_id_volatile));
+
+	smbreq = smbd_smb2_fake_smb_request(req);
+	if (smbreq == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* If it's an IPC, pass off the pipe handler. */
+	if (IS_IPC(conn)) {
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);
+	if (fsp == NULL) {
+		return NT_STATUS_FILE_CLOSED;
+	}
+	if (conn != fsp->conn) {
+		return NT_STATUS_FILE_CLOSED;
+	}
+	if (req->session->vuid != fsp->vuid) {
+		return NT_STATUS_FILE_CLOSED;
+	}
+
+	status = close_file(smbreq, fsp, NORMAL_CLOSE);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(5,("smbd_smb2_close: close_file[%s]: %s\n",
+			fsp->fsp_name, nt_errstr(status)));
+		return status;
+	}
+
+	return NT_STATUS_OK;
+}
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
new file mode 100644
index 0000000..8cd0c3b
--- /dev/null
+++ b/source3/smbd/smb2_create.c
@@ -0,0 +1,274 @@
+/*
+   Unix SMB/CIFS implementation.
+   Core SMB2 server
+
+   Copyright (C) Stefan Metzmacher 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/globals.h"
+#include "../source4/libcli/smb2/smb2_constants.h"
+
+static NTSTATUS smbd_smb2_create(struct smbd_smb2_request *req,
+				 uint8_t in_oplock_level,
+				 uint32_t in_impersonation_level,
+				 uint32_t in_desired_access,
+				 uint32_t in_file_attributes,
+				 uint32_t in_share_access,
+				 uint32_t in_create_disposition,
+				 uint32_t in_create_options,
+				 const char *in_name,
+				 uint8_t *out_oplock_level,
+				 uint32_t *out_create_action,
+				 NTTIME *out_creation_time,
+				 NTTIME *out_last_access_time,
+				 NTTIME *out_last_write_time,
+				 NTTIME *out_change_time,
+				 uint64_t *out_allocation_size,
+				 uint64_t *out_end_of_file,
+				 uint32_t *out_file_attributes,
+				 uint64_t *out_file_id_volatile);
+
+NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *req)
+{
+	const uint8_t *inbody;
+	int i = req->current_idx;
+	uint8_t *outhdr;
+	DATA_BLOB outbody;
+	DATA_BLOB outdyn;
+	size_t expected_body_size = 0x39;
+	size_t body_size;
+	uint8_t in_oplock_level;
+	uint32_t in_impersonation_level;
+	uint32_t in_desired_access;
+	uint32_t in_file_attributes;
+	uint32_t in_share_access;
+	uint32_t in_create_disposition;
+	uint32_t in_create_options;
+	uint16_t in_name_offset;
+	uint16_t in_name_length;
+	DATA_BLOB in_name_buffer;
+	char *in_name_string;
+	size_t in_name_string_size;
+	uint8_t out_oplock_level;
+	uint32_t out_create_action;
+	NTTIME out_creation_time;
+	NTTIME out_last_access_time;
+	NTTIME out_last_write_time;
+	NTTIME out_change_time;
+	uint64_t out_allocation_size;
+	uint64_t out_end_of_file;
+	uint32_t out_file_attributes;
+	uint64_t out_file_id_volatile;
+	NTSTATUS status;
+	bool ok;
+
+	if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
+		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	}
+
+	inbody = (const uint8_t *)req->in.vector[i+1].iov_base;
+
+	body_size = SVAL(inbody, 0x00);
+	if (body_size != expected_body_size) {
+		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	}
+
+	in_oplock_level		= CVAL(inbody, 0x03);
+	in_impersonation_level	= IVAL(inbody, 0x04);
+	in_desired_access	= IVAL(inbody, 0x18);
+	in_file_attributes	= IVAL(inbody, 0x1C);
+	in_share_access		= IVAL(inbody, 0x20);
+	in_create_disposition	= IVAL(inbody, 0x24);
+	in_create_options	= IVAL(inbody, 0x28);
+	in_name_offset		= SVAL(inbody, 0x2C);
+	in_name_length		= SVAL(inbody, 0x2E);
+
+	if (in_name_offset != (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {
+		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	}
+
+	if (in_name_length > req->in.vector[i+2].iov_len) {
+		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	}
+
+	in_name_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base;
+	in_name_buffer.length = in_name_length;
+
+	ok = convert_string_talloc(req, CH_UTF16, CH_UNIX,
+				   in_name_buffer.data,
+				   in_name_buffer.length,
+				   &in_name_string,
+				   &in_name_string_size, false);
+	if (!ok) {
+		return smbd_smb2_request_error(req, NT_STATUS_ILLEGAL_CHARACTER);
+	}
+
+	status = smbd_smb2_create(req,
+				  in_oplock_level,
+				  in_impersonation_level,
+				  in_desired_access,
+				  in_file_attributes,
+				  in_share_access,
+				  in_create_disposition,
+				  in_create_options,
+				  in_name_string,
+				  &out_oplock_level,
+				  &out_create_action,
+				  &out_creation_time,
+				  &out_last_access_time,
+				  &out_last_write_time,
+				  &out_change_time,
+				  &out_allocation_size,
+				  &out_end_of_file,
+				  &out_file_attributes,
+				  &out_file_id_volatile);
+	if (!NT_STATUS_IS_OK(status)) {
+		return smbd_smb2_request_error(req, status);
+	}
+
+	outhdr = (uint8_t *)req->out.vector[i].iov_base;
+
+	outbody = data_blob_talloc(req->out.vector, NULL, 0x58);
+	if (outbody.data == NULL) {
+		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
+	}
+
+	SSVAL(outbody.data, 0x00, 0x58 + 1);	/* struct size */
+	SCVAL(outbody.data, 0x02,
+	      out_oplock_level);		/* oplock level */
+	SCVAL(outbody.data, 0x03, 0);		/* reserved */
+	SIVAL(outbody.data, 0x04,
+	      out_create_action);		/* create action */
+	SBVAL(outbody.data, 0x08,
+	      out_creation_time);		/* creation time */
+	SBVAL(outbody.data, 0x10,
+	      out_last_access_time);		/* last access time */
+	SBVAL(outbody.data, 0x18,
+	      out_last_write_time);		/* last write time */
+	SBVAL(outbody.data, 0x20,
+	      out_change_time);			/* change time */
+	SBVAL(outbody.data, 0x28,
+	      out_allocation_size);		/* allocation size */
+	SBVAL(outbody.data, 0x30,
+	      out_end_of_file);			/* end of file */
+	SIVAL(outbody.data, 0x38,
+	      out_file_attributes);		/* file attributes */
+	SIVAL(outbody.data, 0x3C, 0);		/* reserved */
+	SBVAL(outbody.data, 0x40, 0);		/* file id (persistent) */
+	SBVAL(outbody.data, 0x48,
+	      out_file_id_volatile);		/* file id (volatile) */
+	SIVAL(outbody.data, 0x50, 0);		/* create contexts offset */
+	SIVAL(outbody.data, 0x54, 0);		/* create contexts length */
+
+	outdyn = data_blob_const(NULL, 0);
+
+	return smbd_smb2_request_done(req, outbody, &outdyn);
+}
+
+static NTSTATUS smbd_smb2_create(struct smbd_smb2_request *req,
+				 uint8_t in_oplock_level,
+				 uint32_t in_impersonation_level,
+				 uint32_t in_desired_access,
+				 uint32_t in_file_attributes,
+				 uint32_t in_share_access,
+				 uint32_t in_create_disposition,
+				 uint32_t in_create_options,
+				 const char *in_name,
+				 uint8_t *out_oplock_level,
+				 uint32_t *out_create_action,
+				 NTTIME *out_creation_time,
+				 NTTIME *out_last_access_time,
+				 NTTIME *out_last_write_time,
+				 NTTIME *out_change_time,
+				 uint64_t *out_allocation_size,
+				 uint64_t *out_end_of_file,
+				 uint32_t *out_file_attributes,
+				 uint64_t *out_file_id_volatile)
+{
+	NTSTATUS status;
+	struct smb_request *smbreq;
+	files_struct *result;
+	int info;
+	SMB_STRUCT_STAT sbuf;
+
+	DEBUG(10,("smbd_smb2_create: name[%s]\n",
+		  in_name));
+
+	smbreq = smbd_smb2_fake_smb_request(req);
+	if (smbreq == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* If it's an IPC, pass off the pipe handler. */
+	if (IS_IPC(req->tcon->compat_conn)) {
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	if (CAN_PRINT(req->tcon->compat_conn)) {
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	switch (in_oplock_level) {
+	case SMB2_OPLOCK_LEVEL_BATCH:
+		break;
+	case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
+		break;
+	default:
+		break;
+	}
+
+	status = SMB_VFS_CREATE_FILE(req->tcon->compat_conn,
+				     smbreq,
+				     0, /* root_dir_fid */
+				     in_name,
+				     CFF_DOS_PATH, /* create_file_flags */
+				     in_desired_access,
+				     in_share_access,
+				     in_create_disposition,
+				     in_create_options,
+				     in_file_attributes,
+				     0, /* oplock_request */
+				     0, /* allocation_size */


-- 
Samba Shared Repository


More information about the samba-cvs mailing list