From 92b9b83b70aef5ec77f3944f495205c107c6921a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Nov 2005 16:16:09 +0000 Subject: r11650: - as every call that goes down to the ntvfs layer need a valid tcon and session ntcancel also needs to have AS_USER - move the SIGNING_NO_REPLY logic as global option, because this needs to be set for the error replies too. - as we currently don't know how to generate signatures for ntcancel replies we just skip the sending of the reply - w2k3 first checks the VUID and then the TID, so we do now - ntcreateX also uses ERRbaduid when getting a wrong VUID metze (This used to be commit d677ebf43d0d7e679ff11862683c993d887d9441) --- source4/smb_server/reply.c | 1 - source4/smb_server/smb_server.c | 59 +++++++++++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/source4/smb_server/reply.c b/source4/smb_server/reply.c index 85edbb530f..4526d6f7f3 100644 --- a/source4/smb_server/reply.c +++ b/source4/smb_server/reply.c @@ -2335,7 +2335,6 @@ void reply_ntcreate_and_X(struct smbsrv_request *req) void reply_ntcancel(struct smbsrv_request *req) { /* NOTE: this request does not generate a reply */ - req_signing_no_reply(req); ntvfs_cancel(req); req_destroy(req); } diff --git a/source4/smb_server/smb_server.c b/source4/smb_server/smb_server.c index 0a28023e46..1467beccac 100644 --- a/source4/smb_server/smb_server.c +++ b/source4/smb_server/smb_server.c @@ -114,6 +114,7 @@ static NTSTATUS receive_smb_request(void *private, DATA_BLOB blob) These flags determine some of the permissions required to do an operation */ #define AS_USER (1<<0) +#define SIGNING_NO_REPLY (1<<1) /* define a list of possible SMB messages and their corresponding @@ -291,7 +292,7 @@ static const struct smb_message_struct /* 0xa1 */ { "SMBnttranss", reply_nttranss, AS_USER}, /* 0xa2 */ { "SMBntcreateX", reply_ntcreate_and_X, AS_USER}, /* 0xa3 */ { NULL, NULL, 0 }, -/* 0xa4 */ { "SMBntcancel", reply_ntcancel, 0}, +/* 0xa4 */ { "SMBntcancel", reply_ntcancel, AS_USER|SIGNING_NO_REPLY}, /* 0xa5 */ { "SMBntrename", reply_ntrename, AS_USER}, /* 0xa6 */ { NULL, NULL, 0 }, /* 0xa7 */ { NULL, NULL, 0 }, @@ -411,6 +412,7 @@ static void switch_message(int type, struct smbsrv_request *req) int flags; struct smbsrv_connection *smb_conn = req->smb_conn; uint16_t session_tag; + NTSTATUS status; type &= 0xff; @@ -448,23 +450,64 @@ static void switch_message(int type, struct smbsrv_request *req) DEBUG(3,("switch message %s (task_id %d)\n",smb_fn_name(type), req->smb_conn->connection->server_id)); - /* does this protocol need a valid tree connection? */ - if ((flags & AS_USER) && !req->tcon) { + /* this must be called before we do any reply */ + if (flags & SIGNING_NO_REPLY) { + req_signing_no_reply(req); + } + + /* see if the vuid is valid */ + if ((flags & AS_USER) && !req->session) { /* amazingly, the error code depends on the command */ switch (type) { case SMBntcreateX: - req_reply_error(req, NT_STATUS_DOS(ERRSRV, ERRinvnid)); + case SMBntcancel: + status = NT_STATUS_DOS(ERRSRV, ERRbaduid); break; default: - req_reply_error(req, NT_STATUS_INVALID_HANDLE); + status = NT_STATUS_INVALID_HANDLE; break; } + /* + * TODO: + * don't know how to handle smb signing for this case + * so just skip the reply + */ + if ((flags & SIGNING_NO_REPLY) && + (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF)) { + DEBUG(1,("SKIP ERROR REPLY: %s %s because of unknown smb signing case\n", + smb_fn_name(type), nt_errstr(status))); + req_destroy(req); + return; + } + req_reply_error(req, status); return; } - /* see if the vuid is valid */ - if ((flags & AS_USER) && !req->session) { - req_reply_error(req, NT_STATUS_INVALID_HANDLE); + /* does this protocol need a valid tree connection? */ + if ((flags & AS_USER) && !req->tcon) { + /* amazingly, the error code depends on the command */ + switch (type) { + case SMBntcreateX: + case SMBntcancel: + status = NT_STATUS_DOS(ERRSRV, ERRinvnid); + break; + default: + status = NT_STATUS_INVALID_HANDLE; + break; + } + /* + * TODO: + * don't know how to handle smb signing for this case + * so just skip the reply + */ + if ((flags & SIGNING_NO_REPLY) && + (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF)) { + DEBUG(1,("SKIP ERROR REPLY: %s %s because of unknown smb signing case\n", + smb_fn_name(type), nt_errstr(status))); + req_destroy(req); + return; + } + req_reply_error(req, status); return; } -- cgit