s4-server: use GUID_to_ndr_blob() in cldap and smb servers
[samba.git] / source4 / smb_server / smb2 / negprot.c
index d64b36d659c010a98edca7b04ef68acad47fc0dd..260822f2c5f5da2ac988e454cbe814c6cc9ccd4f 100644 (file)
 
 #include "includes.h"
 #include "auth/credentials/credentials.h"
+#include "auth/auth.h"
 #include "auth/gensec/gensec.h"
 #include "libcli/raw/libcliraw.h"
 #include "libcli/raw/raw_proto.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 "smbd/service_stream.h"
 #include "param/param.h"
-#include "librpc/ndr/libndr.h"
 
 static NTSTATUS smb2srv_negprot_secblob(struct smb2srv_request *req, DATA_BLOB *_blob)
 {
@@ -40,17 +39,6 @@ static NTSTATUS smb2srv_negprot_secblob(struct smb2srv_request *req, DATA_BLOB *
        NTSTATUS nt_status;
        struct cli_credentials *server_credentials;
 
-       nt_status = gensec_server_start(req,
-                                       req->smb_conn->connection->event.ctx,
-                                       req->smb_conn->lp_ctx,
-                                       req->smb_conn->connection->msg_ctx,
-                                       &gensec_security);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               DEBUG(0, ("Failed to start GENSEC: %s\n", nt_errstr(nt_status)));
-               smbsrv_terminate_connection(req->smb_conn, "Failed to start GENSEC\n");
-               return nt_status;
-       }
-
        server_credentials = cli_credentials_init(req);
        if (!server_credentials) {
                smbsrv_terminate_connection(req->smb_conn, "Failed to init server credentials\n");
@@ -67,6 +55,19 @@ static NTSTATUS smb2srv_negprot_secblob(struct smb2srv_request *req, DATA_BLOB *
 
        req->smb_conn->negotiate.server_credentials = talloc_steal(req->smb_conn, server_credentials);
 
+       nt_status = samba_server_gensec_start(req,
+                                             req->smb_conn->connection->event.ctx,
+                                             req->smb_conn->connection->msg_ctx,
+                                             req->smb_conn->lp_ctx,
+                                             server_credentials,
+                                             "cifs",
+                                             &gensec_security);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(0, ("Failed to start GENSEC: %s\n", nt_errstr(nt_status)));
+               smbsrv_terminate_connection(req->smb_conn, "Failed to start GENSEC\n");
+               return nt_status;
+       }
+
        gensec_set_target_service(gensec_security, "cifs");
 
        gensec_set_credentials(gensec_security, server_credentials);
@@ -94,14 +95,21 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
        NTSTATUS status;
        struct timeval current_time;
        struct timeval boot_time;
+       uint16_t i;
+       uint16_t dialect = 0;
 
        /* we only do one dialect for now */
        if (io->in.dialect_count < 1) {
                return NT_STATUS_NOT_SUPPORTED;
        }
-       if (io->in.dialects[0] != 0 &&
-           io->in.dialects[0] != SMB2_DIALECT_REVISION) {
-               DEBUG(0,("Got unexpected SMB2 dialect %u\n", io->in.dialects[0]));
+       for (i=0; i < io->in.dialect_count; i++) {
+               dialect = io->in.dialects[i];
+               if (dialect == SMB2_DIALECT_REVISION_202) {
+                       break;
+               }
+       }
+       if (dialect != SMB2_DIALECT_REVISION_202) {
+               DEBUG(0,("Got unexpected SMB2 dialect %u\n", dialect));
                return NT_STATUS_NOT_SUPPORTED;
        }
 
@@ -125,7 +133,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
                req->smb_conn->smb2_signing_required = true;
                break;
        }
-       io->out.dialect_revision   = SMB2_DIALECT_REVISION;
+       io->out.dialect_revision   = dialect;
        io->out.capabilities       = 0;
        io->out.max_transact_size  = lp_parm_ulong(req->smb_conn->lp_ctx, NULL, 
                                                   "smb2", "max transaction size", 0x10000);
@@ -145,7 +153,6 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
 static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negprot *io)
 {
        NTSTATUS status;
-       enum ndr_err_code ndr_err;
 
        if (NT_STATUS_IS_ERR(req->status)) {
                smb2srv_send_error(req, req->status); /* TODO: is this correct? */
@@ -162,8 +169,8 @@ static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negpro
        SSVAL(req->out.body, 0x02, io->out.security_mode);
        SIVAL(req->out.body, 0x04, io->out.dialect_revision);
        SIVAL(req->out.body, 0x06, io->out.reserved);
-       ndr_err = smbcli_push_guid(req->out.body, 0x08, &io->out.server_guid);
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+       status = smbcli_push_guid(req->out.body, 0x08, &io->out.server_guid);
+       if (!NT_STATUS_IS_OK(status)) {
                smbsrv_terminate_connection(req->smb_conn, nt_errstr(status));
                talloc_free(req);
                return;
@@ -189,10 +196,9 @@ void smb2srv_negprot_recv(struct smb2srv_request *req)
 {
        struct smb2_negprot *io;
        int i;
-       enum ndr_err_code ndr_err;
 
        if (req->in.body_size < 0x26) {
-               smb2srv_send_error(req,  NT_STATUS_FOOBAR);
+               smbsrv_terminate_connection(req->smb_conn, "Bad body size in SMB2 negprot");
                return;
        }
 
@@ -207,9 +213,9 @@ void smb2srv_negprot_recv(struct smb2srv_request *req)
        io->in.security_mode = SVAL(req->in.body, 0x04);
        io->in.reserved      = SVAL(req->in.body, 0x06);
        io->in.capabilities  = IVAL(req->in.body, 0x08);
-       ndr_err = smbcli_pull_guid(req->in.body, 0xC, &io->in.client_guid);
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_FOOBAR));
+       req->status = smbcli_pull_guid(req->in.body, 0xC, &io->in.client_guid);
+       if (!NT_STATUS_IS_OK(req->status)) {
+               smbsrv_terminate_connection(req->smb_conn, "Bad GUID in SMB2 negprot");
                talloc_free(req);
                return;
        }
@@ -278,7 +284,7 @@ void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req)
 
        SSVAL(req->in.body, 0x02, 1);
        memset(req->in.body+0x04, 0, 32);
-       SSVAL(req->in.body, 0x24, 0);
+       SSVAL(req->in.body, 0x24, SMB2_DIALECT_REVISION_202);
 
        smb2srv_negprot_recv(req);
        return;