Remove auth/ntlm as a dependency of GENSEC by means of function pointers.
[kai/samba-autobuild/.git] / source4 / smb_server / smb / negprot.c
index a35f86367b9aed2007064dd070df9371225949e4..c3399fdd4899bc1e329c692a8dc4b1b5e0f59498 100644 (file)
@@ -47,6 +47,7 @@ static NTSTATUS get_challenge(struct smbsrv_connection *smb_conn, uint8_t buff[8
        nt_status = auth_context_create(smb_conn, 
                                        smb_conn->connection->event.ctx,
                                        smb_conn->connection->msg_ctx,
+                                       smb_conn->lp_ctx,
                                        &smb_conn->negotiate.auth_context);
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(0, ("auth_context_create() returned %s", nt_errstr(nt_status)));
@@ -91,7 +92,7 @@ this any more it probably doesn't matter
 ****************************************************************************/
 static void reply_coreplus(struct smbsrv_request *req, uint16_t choice)
 {
-       uint16_t raw = (lp_readraw(global_loadparm)?1:0) | (lp_writeraw(global_loadparm)?2:0);
+       uint16_t raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0);
 
        smbsrv_setup_reply(req, 13, 0);
 
@@ -122,13 +123,13 @@ static void reply_coreplus(struct smbsrv_request *req, uint16_t choice)
 ****************************************************************************/
 static void reply_lanman1(struct smbsrv_request *req, uint16_t choice)
 {
-       int raw = (lp_readraw(global_loadparm)?1:0) | (lp_writeraw(global_loadparm)?2:0);
+       int raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0);
        int secword=0;
        time_t t = req->request_time.tv_sec;
 
-       req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(global_loadparm);
+       req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx);
 
-       if (lp_security(global_loadparm) != SEC_SHARE)
+       if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE)
                secword |= NEGOTIATE_SECURITY_USER_LEVEL;
 
        if (req->smb_conn->negotiate.encrypted_passwords)
@@ -145,7 +146,7 @@ static void reply_lanman1(struct smbsrv_request *req, uint16_t choice)
        SSVAL(req->out.vwv, VWV(0), choice);
        SSVAL(req->out.vwv, VWV(1), secword); 
        SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv);
-       SSVAL(req->out.vwv, VWV(3), lp_maxmux(global_loadparm));
+       SSVAL(req->out.vwv, VWV(3), lp_maxmux(req->smb_conn->lp_ctx));
        SSVAL(req->out.vwv, VWV(4), 1);
        SSVAL(req->out.vwv, VWV(5), raw); 
        SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.id);
@@ -180,13 +181,13 @@ static void reply_lanman1(struct smbsrv_request *req, uint16_t choice)
 ****************************************************************************/
 static void reply_lanman2(struct smbsrv_request *req, uint16_t choice)
 {
-       int raw = (lp_readraw(global_loadparm)?1:0) | (lp_writeraw(global_loadparm)?2:0);
+       int raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0);
        int secword=0;
        time_t t = req->request_time.tv_sec;
 
-       req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(global_loadparm);
+       req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx);
   
-       if (lp_security(global_loadparm) != SEC_SHARE)
+       if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE)
                secword |= NEGOTIATE_SECURITY_USER_LEVEL;
 
        if (req->smb_conn->negotiate.encrypted_passwords)
@@ -199,7 +200,7 @@ static void reply_lanman2(struct smbsrv_request *req, uint16_t choice)
        SSVAL(req->out.vwv, VWV(0), choice);
        SSVAL(req->out.vwv, VWV(1), secword); 
        SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv);
-       SSVAL(req->out.vwv, VWV(3), lp_maxmux(global_loadparm));
+       SSVAL(req->out.vwv, VWV(3), lp_maxmux(req->smb_conn->lp_ctx));
        SSVAL(req->out.vwv, VWV(4), 1);
        SSVAL(req->out.vwv, VWV(5), raw); 
        SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.id);
@@ -214,7 +215,7 @@ static void reply_lanman2(struct smbsrv_request *req, uint16_t choice)
                get_challenge(req->smb_conn, req->out.data);
        }
 
-       req_push_str(req, NULL, lp_workgroup(global_loadparm), -1, STR_TERMINATE);
+       req_push_str(req, NULL, lp_workgroup(req->smb_conn->lp_ctx), -1, STR_TERMINATE);
 
        if (req->smb_conn->signing.mandatory_signing) {
                smbsrv_terminate_connection(req->smb_conn, 
@@ -236,8 +237,8 @@ static void reply_nt1_orig(struct smbsrv_request *req)
                req->out.ptr += 8;
                SCVAL(req->out.vwv+1, VWV(16), 8);
        }
-       req_push_str(req, NULL, lp_workgroup(global_loadparm), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
-       req_push_str(req, NULL, lp_netbios_name(global_loadparm), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
+       req_push_str(req, NULL, lp_workgroup(req->smb_conn->lp_ctx), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
+       req_push_str(req, NULL, lp_netbios_name(req->smb_conn->lp_ctx), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
        DEBUG(3,("not using extended security (SPNEGO or NTLMSSP)\n"));
 }
 
@@ -251,7 +252,7 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
        int secword=0;
        time_t t = req->request_time.tv_sec;
        NTTIME nttime;
-       BOOL negotiate_spnego = False;
+       bool negotiate_spnego = false;
        char *large_test_path;
 
        unix_to_nt_time(&nttime, t);
@@ -260,50 +261,51 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
                CAP_NT_FIND | CAP_LOCK_AND_READ | 
                CAP_LEVEL_II_OPLOCKS | CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
 
-       req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(global_loadparm);
+       req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx);
 
        /* do spnego in user level security if the client
           supports it and we can do encrypted passwords */
        
        if (req->smb_conn->negotiate.encrypted_passwords && 
-           (lp_security(global_loadparm) != SEC_SHARE) &&
-           lp_use_spnego(global_loadparm) &&
+           (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) &&
+           lp_use_spnego(req->smb_conn->lp_ctx) &&
            (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
-               negotiate_spnego = True; 
+               negotiate_spnego = true; 
                capabilities |= CAP_EXTENDED_SECURITY;
        }
        
-       if (lp_unix_extensions(global_loadparm)) {
+       if (lp_unix_extensions(req->smb_conn->lp_ctx)) {
                capabilities |= CAP_UNIX;
        }
        
-       if (lp_large_readwrite(global_loadparm)) {
+       if (lp_large_readwrite(req->smb_conn->lp_ctx)) {
                capabilities |= CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS;
        }
 
-       large_test_path = lock_path(req, "large_test.dat");
+       large_test_path = lock_path(req, req->smb_conn->lp_ctx, "large_test.dat");
        if (large_file_support(large_test_path)) {
                capabilities |= CAP_LARGE_FILES;
        }
 
-       if (lp_readraw(global_loadparm) && lp_writeraw(global_loadparm)) {
+       if (lp_readraw(req->smb_conn->lp_ctx) && 
+           lp_writeraw(req->smb_conn->lp_ctx)) {
                capabilities |= CAP_RAW_MODE;
        }
        
        /* allow for disabling unicode */
-       if (lp_unicode(global_loadparm)) {
+       if (lp_unicode(req->smb_conn->lp_ctx)) {
                capabilities |= CAP_UNICODE;
        }
 
-       if (lp_nt_status_support(global_loadparm)) {
+       if (lp_nt_status_support(req->smb_conn->lp_ctx)) {
                capabilities |= CAP_STATUS32;
        }
        
-       if (lp_host_msdfs(global_loadparm)) {
+       if (lp_host_msdfs(req->smb_conn->lp_ctx)) {
                capabilities |= CAP_DFS;
        }
        
-       if (lp_security(global_loadparm) != SEC_SHARE) {
+       if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) {
                secword |= NEGOTIATE_SECURITY_USER_LEVEL;
        }
 
@@ -330,7 +332,7 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
           this is the one and only SMB packet that is malformed in
           the specification - all the command words after the secword
           are offset by 1 byte */
-       SSVAL(req->out.vwv+1, VWV(1), lp_maxmux(global_loadparm));
+       SSVAL(req->out.vwv+1, VWV(1), lp_maxmux(req->smb_conn->lp_ctx));
        SSVAL(req->out.vwv+1, VWV(2), 1); /* num vcs */
        SIVAL(req->out.vwv+1, VWV(3), req->smb_conn->negotiate.max_recv);
        SIVAL(req->out.vwv+1, VWV(5), 0x10000); /* raw size. full 64k */
@@ -348,22 +350,7 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
                DATA_BLOB blob;
                const char *oid;
                NTSTATUS nt_status;
-
-               nt_status = gensec_server_start(req->smb_conn,
-                                               req->smb_conn->connection->event.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;
-               }
-
-               if (req->smb_conn->negotiate.auth_context) {
-                       smbsrv_terminate_connection(req->smb_conn, "reply_nt1: is this a secondary negprot?  auth_context is non-NULL!\n");
-                       return;
-               }
-
+               
                server_credentials 
                        = cli_credentials_init(req);
                if (!server_credentials) {
@@ -371,14 +358,32 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
                        return;
                }
                
-               cli_credentials_set_conf(server_credentials, global_loadparm);
-               nt_status = cli_credentials_set_machine_account(server_credentials);
+               cli_credentials_set_conf(server_credentials, req->smb_conn->lp_ctx);
+               nt_status = cli_credentials_set_machine_account(server_credentials, req->smb_conn->lp_ctx);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status)));
                        talloc_free(server_credentials);
                        server_credentials = NULL;
                }
 
+               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;
+               }
+
+               if (req->smb_conn->negotiate.auth_context) {
+                       smbsrv_terminate_connection(req->smb_conn, "reply_nt1: is this a secondary negprot?  auth_context is non-NULL!\n");
+                       return;
+               }
                req->smb_conn->negotiate.server_credentials = talloc_steal(req->smb_conn, server_credentials);
 
                gensec_set_target_service(gensec_security, "cifs");
@@ -463,6 +468,7 @@ static const struct {
        void (*proto_reply_fn)(struct smbsrv_request *req, uint16_t choice);
        int protocol_level;
 } supported_protocols[] = {
+       {"SMB 2.002",                   "SMB2",         reply_smb2,     PROTOCOL_SMB2},
        {"SMB 2.001",                   "SMB2",         reply_smb2,     PROTOCOL_SMB2},
        {"NT LANMAN 1.0",               "NT1",          reply_nt1,      PROTOCOL_NT1},
        {"NT LM 0.12",                  "NT1",          reply_nt1,      PROTOCOL_NT1},
@@ -493,10 +499,10 @@ void smbsrv_reply_negprot(struct smbsrv_request *req)
                smbsrv_terminate_connection(req->smb_conn, "multiple negprot's are not permitted");
                return;
        }
-       req->smb_conn->negotiate.done_negprot = True;
+       req->smb_conn->negotiate.done_negprot = true;
 
        p = req->in.data;
-       while (True) {
+       while (true) {
                size_t len;
 
                protos = talloc_realloc(req, protos, char *, protos_count + 1);
@@ -505,7 +511,7 @@ void smbsrv_reply_negprot(struct smbsrv_request *req)
                        return;
                }
                protos[protos_count] = NULL;
-               len = req_pull_ascii4(req, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE);
+               len = req_pull_ascii4(&req->in.bufinfo, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE);
                p += len;
                if (len == 0 || !protos[protos_count]) break;
 
@@ -517,9 +523,9 @@ void smbsrv_reply_negprot(struct smbsrv_request *req)
        for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
                int i;
 
-               if (supported_protocols[protocol].protocol_level > lp_srv_maxprotocol(global_loadparm)) 
+               if (supported_protocols[protocol].protocol_level > lp_srv_maxprotocol(req->smb_conn->lp_ctx)) 
                        continue;
-               if (supported_protocols[protocol].protocol_level < lp_srv_minprotocol(global_loadparm)) 
+               if (supported_protocols[protocol].protocol_level < lp_srv_minprotocol(req->smb_conn->lp_ctx)) 
                        continue;
 
                for (i = 0; i < protos_count; i++) {