diff options
-rw-r--r-- | source4/smb_server/reply.c | 1 | ||||
-rw-r--r-- | 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; } |