svn commit: samba r15753 - in branches/SAMBA_4_0/source/smb_server/smb2: .

metze at samba.org metze at samba.org
Sat May 20 17:06:29 GMT 2006


Author: metze
Date: 2006-05-20 17:06:28 +0000 (Sat, 20 May 2006)
New Revision: 15753

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=15753

Log:
implement SMB2 Create

metze
Modified:
   branches/SAMBA_4_0/source/smb_server/smb2/fileio.c
   branches/SAMBA_4_0/source/smb_server/smb2/smb2_server.h


Changeset:
Modified: branches/SAMBA_4_0/source/smb_server/smb2/fileio.c
===================================================================
--- branches/SAMBA_4_0/source/smb_server/smb2/fileio.c	2006-05-20 16:53:44 UTC (rev 15752)
+++ branches/SAMBA_4_0/source/smb_server/smb2/fileio.c	2006-05-20 17:06:28 UTC (rev 15753)
@@ -20,11 +20,63 @@
 
 #include "includes.h"
 #include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+#include "smb_server/smb_server.h"
+#include "smb_server/service_smb_proto.h"
 #include "smb_server/smb2/smb2_server.h"
+#include "ntvfs/ntvfs.h"
 
+static void smb2srv_create_send(struct ntvfs_request *ntvfs)
+{
+	struct smb2srv_request *req;
+	union smb_open *io;
+
+	SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_open);
+	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x58, True, io->smb2.out.blob.length));
+
+	SSVAL(req->out.body,	0x02,	io->smb2.out.oplock_flags);
+	SIVAL(req->out.body,	0x04,	io->smb2.out.create_action);
+	SBVAL(req->out.body,	0x08,	io->smb2.out.create_time);
+	SBVAL(req->out.body,	0x10,	io->smb2.out.access_time);
+	SBVAL(req->out.body,	0x18,	io->smb2.out.write_time);
+	SBVAL(req->out.body,	0x20,	io->smb2.out.change_time);
+	SBVAL(req->out.body,	0x28,	io->smb2.out.alloc_size);
+	SBVAL(req->out.body,	0x30,	io->smb2.out.size);
+	SIVAL(req->out.body,	0x38,	io->smb2.out.file_attr);
+	SIVAL(req->out.body,	0x3C,	io->smb2.out._pad);
+	smb2srv_push_handle(req->out.body, 0x40,io->smb2.out.file.ntvfs);
+	SMB2SRV_CHECK(smb2_push_o16s16_blob(&req->out, 0x50, io->smb2.out.blob));
+
+	smb2srv_send_reply(req);
+}
+
 void smb2srv_create_recv(struct smb2srv_request *req)
 {
-	smb2srv_send_error(req, NT_STATUS_NOT_IMPLEMENTED);
+	union smb_open *io;
+	DATA_BLOB blob;
+
+	SMB2SRV_CHECK_BODY_SIZE(req, 0x38, True);
+	SMB2SRV_TALLOC_IO_PTR(io, union smb_open);
+	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_create_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
+
+	io->smb2.level			= RAW_OPEN_SMB2;
+	io->smb2.in.oplock_flags	= SVAL(req->in.body, 0x02);
+	io->smb2.in.impersonation	= IVAL(req->in.body, 0x04);
+	io->smb2.in.unknown3[0]		= IVAL(req->in.body, 0x08);
+	io->smb2.in.unknown3[1]		= IVAL(req->in.body, 0x0C);
+	io->smb2.in.unknown3[2]		= IVAL(req->in.body, 0x10);
+	io->smb2.in.unknown3[3]		= IVAL(req->in.body, 0x14);
+	io->smb2.in.access_mask		= IVAL(req->in.body, 0x18);
+	io->smb2.in.file_attr		= IVAL(req->in.body, 0x1C);
+	io->smb2.in.share_access	= IVAL(req->in.body, 0x20);
+	io->smb2.in.open_disposition	= IVAL(req->in.body, 0x24);
+	io->smb2.in.create_options	= IVAL(req->in.body, 0x28);
+	SMB2SRV_CHECK(smb2_pull_o16s16_string(&req->in, io, req->in.body+0x2C, &io->smb2.in.fname));
+	SMB2SRV_CHECK(smb2_pull_o32s32_blob(&req->in, io, req->in.body+0x30, &blob));
+	/* TODO: parse the blob */
+	ZERO_STRUCT(io->smb2.in.eas);
+
+	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, io));
 }
 
 void smb2srv_close_recv(struct smb2srv_request *req)

Modified: branches/SAMBA_4_0/source/smb_server/smb2/smb2_server.h
===================================================================
--- branches/SAMBA_4_0/source/smb_server/smb2/smb2_server.h	2006-05-20 16:53:44 UTC (rev 15752)
+++ branches/SAMBA_4_0/source/smb_server/smb2/smb2_server.h	2006-05-20 17:06:28 UTC (rev 15753)
@@ -60,3 +60,100 @@
 struct smbsrv_request;
 
 #include "smb_server/smb2/smb2_proto.h"
+
+/* useful way of catching wct errors with file and line number */
+#define SMB2SRV_CHECK_BODY_SIZE(req, size, dynamic) do { \
+	size_t is_size = req->in.body_size; \
+	uint16_t field_size = SVAL(req->in.body, 0); \
+	uint16_t want_size = ((dynamic)?(size)+1:(size)); \
+	if (is_size < (size)) { \
+		DEBUG(0,("%s: buffer too small 0x%x. Expected 0x%x\n", \
+			 __location__, is_size, want_size)); \
+		smb2srv_send_error(req,  NT_STATUS_FOOBAR); \
+	}\
+	if (field_size != want_size) { \
+		DEBUG(0,("%s: unexpected fixed body size 0x%x. Expected 0x%x\n", \
+			 __location__, field_size, want_size)); \
+		smb2srv_send_error(req,  NT_STATUS_FOOBAR); \
+	} \
+} while (0)
+
+#define SMB2SRV_CHECK(cmd) do {\
+	NTSTATUS _status; \
+	_status = cmd; \
+	if (!NT_STATUS_IS_OK(_status)) { \
+		smb2srv_send_error(req,  _status); \
+		return; \
+	} \
+} while (0)
+
+/* useful wrapper for talloc with NO_MEMORY reply */
+#define SMB2SRV_TALLOC_IO_PTR(ptr, type) do { \
+	ptr = talloc(req, type); \
+	if (!ptr) { \
+		smb2srv_send_error(req, NT_STATUS_NO_MEMORY); \
+		return; \
+	} \
+	req->io_ptr = ptr; \
+} while (0)
+
+#define SMB2SRV_SETUP_NTVFS_REQUEST(send_fn, state) do { \
+	req->ntvfs = ntvfs_request_create(req->tcon->ntvfs, req, \
+					  req->session->session_info,\
+					  0, \
+					  0, \
+					  req->request_time, \
+					  req, send_fn, state); \
+	if (!req->ntvfs) { \
+		smb2srv_send_error(req, NT_STATUS_NO_MEMORY); \
+		return; \
+	} \
+	if (!talloc_reference(req->ntvfs, req)) { \
+		smb2srv_send_error(req, NT_STATUS_NO_MEMORY); \
+		return; \
+	} \
+	req->ntvfs->frontend_data.private_data = req; \
+} while (0)
+
+#define SMB2SRV_CHECK_FILE_HANDLE(handle) do { \
+	if (!handle) { \
+		smb2srv_send_error(req, NT_STATUS_INVALID_HANDLE); \
+		return; \
+	} \
+} while (0)
+
+/* 
+   check if the backend wants to handle the request asynchronously.
+   if it wants it handled synchronously then call the send function
+   immediately
+*/
+#define SMB2SRV_CALL_NTVFS_BACKEND(cmd) do { \
+	req->ntvfs->async_states->status = cmd; \
+	if (!(req->ntvfs->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \
+		req->ntvfs->async_states->send_fn(req->ntvfs); \
+	} \
+} while (0)
+
+/* check req->ntvfs->async_states->status and if not OK then send an error reply */
+#define SMB2SRV_CHECK_ASYNC_STATUS_ERR_SIMPLE do { \
+	req = talloc_get_type(ntvfs->async_states->private_data, struct smb2srv_request); \
+	if (NT_STATUS_IS_ERR(ntvfs->async_states->status)) { \
+		smb2srv_send_error(req, ntvfs->async_states->status); \
+		return; \
+	} \
+} while (0)
+#define SMB2SRV_CHECK_ASYNC_STATUS_ERR(ptr, type) do { \
+	SMB2SRV_CHECK_ASYNC_STATUS_ERR_SIMPLE; \
+	ptr = talloc_get_type(req->io_ptr, type); \
+} while (0)
+#define SMB2SRV_CHECK_ASYNC_STATUS_SIMPLE do { \
+	req = talloc_get_type(ntvfs->async_states->private_data, struct smb2srv_request); \
+	if (!NT_STATUS_IS_OK(ntvfs->async_states->status)) { \
+		smb2srv_send_error(req, ntvfs->async_states->status); \
+		return; \
+	} \
+} while (0)
+#define SMB2SRV_CHECK_ASYNC_STATUS(ptr, type) do { \
+	SMB2SRV_CHECK_ASYNC_STATUS_SIMPLE; \
+	ptr = talloc_get_type(req->io_ptr, type); \
+} while (0)



More information about the samba-cvs mailing list