Fix Samba4 build errors with common libcli/samsync
[ira/wip.git] / source4 / auth / ntlmssp / ntlmssp_server.c
index 891be43d81ad48ace75ac909b693410486bdfa23..ddc9d565f79771e9dac9365b79f2854ab70087ee 100644 (file)
@@ -9,7 +9,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-#include "auth/auth.h"
+#include "system/network.h"
 #include "auth/ntlmssp/ntlmssp.h"
-#include "lib/crypto/crypto.h"
-#include "pstring.h"
+#include "../libcli/auth/libcli_auth.h"
+#include "../lib/crypto/crypto.h"
+#include "auth/credentials/credentials.h"
+#include "auth/gensec/gensec.h"
+#include "auth/auth.h"
+#include "auth/ntlm/auth_proto.h"
+#include "param/param.h"
+#include "auth/session_proto.h"
 
 /** 
  * Set a username on an NTLMSSP context - ensures it is talloc()ed 
@@ -73,42 +78,6 @@ static NTSTATUS ntlmssp_set_workstation(struct gensec_ntlmssp_state *gensec_ntlm
        return NT_STATUS_OK;
 }
 
-/**
- * Default challenge generation code.
- *
- */
-   
-static const uint8_t *get_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
-{
-       uint8_t *chal = talloc_size(gensec_ntlmssp_state, 8);
-       generate_random_buffer(chal, 8);
-
-       return chal;
-}
-
-/**
- * Default 'we can set the challenge to anything we like' implementation
- *
- */
-   
-static BOOL may_set_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
-{
-       return True;
-}
-
-/**
- * Default 'we can set the challenge to anything we like' implementation
- *
- * Does not actually do anything, as the value is always in the structure anyway.
- *
- */
-   
-static NTSTATUS set_challenge(struct gensec_ntlmssp_state *gensec_ntlmssp_state, DATA_BLOB *challenge)
-{
-       SMB_ASSERT(challenge->length == 8);
-       return NT_STATUS_OK;
-}
-
 /**
  * Determine correct target name flags for reply, given server role 
  * and negotiated flags
@@ -130,13 +99,15 @@ static const char *ntlmssp_target_name(struct gensec_ntlmssp_state *gensec_ntlms
                        return gensec_ntlmssp_state->server_name;
                } else {
                        *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
-                       return gensec_ntlmssp_state->get_domain();
+                       return gensec_ntlmssp_state->domain;
                };
        } else {
                return "";
        }
 }
 
+
+
 /**
  * Next state function for the Negotiate packet
  * 
@@ -151,12 +122,10 @@ NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security,
                                  TALLOC_CTX *out_mem_ctx, 
                                  const DATA_BLOB in, DATA_BLOB *out) 
 {
-       struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+       struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
        DATA_BLOB struct_blob;
-       fstring dnsname, dnsdomname;
        uint32_t neg_flags = 0;
        uint32_t ntlmssp_command, chal_flags;
-       char *cliname=NULL, *domname=NULL;
        const uint8_t *cryptkey;
        const char *target_name;
 
@@ -166,18 +135,17 @@ NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security,
 #endif
 
        if (in.length) {
-               if (!msrpc_parse(out_mem_ctx,
-                                &in, "CddAA",
-                                "NTLMSSP",
-                                &ntlmssp_command,
-                                &neg_flags,
-                                &cliname,
-                                &domname)) {
-                       DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
+               if ((in.length < 16) || !msrpc_parse(out_mem_ctx, 
+                                                        &in, "Cdd",
+                                                        "NTLMSSP",
+                                                        &ntlmssp_command,
+                                                        &neg_flags)) {
+                       DEBUG(1, ("ntlmssp_server_negotiate: failed to parse "
+                               "NTLMSSP Negotiate of length %u:\n",
+                               (unsigned int)in.length ));
                        dump_data(2, in.data, in.length);
                        return NT_STATUS_INVALID_PARAMETER;
                }
-               
                debug_ntlmssp_flags(neg_flags);
        }
        
@@ -185,6 +153,10 @@ NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security,
 
        /* Ask our caller what challenge they would like in the packet */
        cryptkey = gensec_ntlmssp_state->get_challenge(gensec_ntlmssp_state);
+       if (!cryptkey) {
+               DEBUG(1, ("ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
+               return NT_STATUS_INTERNAL_ERROR;
+       }
 
        /* Check if we may set the challenge */
        if (!gensec_ntlmssp_state->may_set_challenge(gensec_ntlmssp_state)) {
@@ -207,18 +179,24 @@ NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security,
        gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8);
        gensec_ntlmssp_state->internal_chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8);
 
-       /* This should be a 'netbios domain -> DNS domain' mapping */
-       dnsdomname[0] = '\0';
-       get_mydomname(dnsdomname);
-       strlower_m(dnsdomname);
-       
-       dnsname[0] = '\0';
-       get_myfullname(dnsname);
-       
        /* This creates the 'blob' of names that appears at the end of the packet */
-       if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) 
-       {
+       if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
+               char dnsdomname[MAXHOSTNAMELEN], dnsname[MAXHOSTNAMELEN];
                const char *target_name_dns = "";
+
+               /* Find out the DNS domain name */
+               dnsdomname[0] = '\0';
+               safe_strcpy(dnsdomname, lp_realm(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1);
+               strlower_m(dnsdomname);
+
+               /* Find out the DNS host name */
+               safe_strcpy(dnsname, gensec_ntlmssp_state->server_name, sizeof(dnsname) - 1);
+               if (dnsdomname[0] != '\0') {
+                       safe_strcat(dnsname, ".", sizeof(dnsname) - 1);
+                       safe_strcat(dnsname, dnsdomname, sizeof(dnsname) - 1);
+               }
+               strlower_m(dnsname);
+
                if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
                        target_name_dns = dnsdomname;
                } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
@@ -237,7 +215,7 @@ NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security,
        }
 
        {
-               /* Marshel the packet in the right format, be it unicode or ASCII */
+               /* Marshal the packet in the right format, be it unicode or ASCII */
                const char *gen_string;
                if (gensec_ntlmssp_state->unicode) {
                        gen_string = "CdUdbddB";
@@ -295,6 +273,7 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_ntlmssp_state *gensec_ntlms
        /* zero these out */
        data_blob_free(&gensec_ntlmssp_state->lm_resp);
        data_blob_free(&gensec_ntlmssp_state->nt_resp);
+       data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
 
        gensec_ntlmssp_state->user = NULL;
        gensec_ntlmssp_state->domain = NULL;
@@ -383,13 +362,13 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_ntlmssp_state *gensec_ntlms
                        SMB_ASSERT(gensec_ntlmssp_state->internal_chal.data 
                                   && gensec_ntlmssp_state->internal_chal.length == 8);
                        
-                       gensec_ntlmssp_state->doing_ntlm2 = True;
+                       gensec_ntlmssp_state->doing_ntlm2 = true;
 
-                       memcpy(gensec_ntlmssp_state->ntlm2.session_nonce, gensec_ntlmssp_state->internal_chal.data, 8);
-                       memcpy(&gensec_ntlmssp_state->ntlm2.session_nonce[8], gensec_ntlmssp_state->lm_resp.data, 8);
+                       memcpy(gensec_ntlmssp_state->crypt.ntlm2.session_nonce, gensec_ntlmssp_state->internal_chal.data, 8);
+                       memcpy(&gensec_ntlmssp_state->crypt.ntlm2.session_nonce[8], gensec_ntlmssp_state->lm_resp.data, 8);
                        
                        MD5Init(&md5_session_nonce_ctx);
-                       MD5Update(&md5_session_nonce_ctx, gensec_ntlmssp_state->ntlm2.session_nonce, 16);
+                       MD5Update(&md5_session_nonce_ctx, gensec_ntlmssp_state->crypt.ntlm2.session_nonce, 16);
                        MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
                        
                        gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state, 
@@ -401,7 +380,7 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_ntlmssp_state *gensec_ntlms
                        /* We changed the effective challenge - set it */
                        if (!NT_STATUS_IS_OK(nt_status = 
                                             gensec_ntlmssp_state->set_challenge(gensec_ntlmssp_state, 
-                                                                         &gensec_ntlmssp_state->chal))) {
+                                                                                &gensec_ntlmssp_state->chal))) {
                                /* zero this out */
                                data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
                                return nt_status;
@@ -422,10 +401,11 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_ntlmssp_state *gensec_ntlms
  * @return Errors or NT_STATUS_OK. 
  */
 
-static NTSTATUS ntlmssp_server_postauth(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
+static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, 
                                        DATA_BLOB *user_session_key, 
                                        DATA_BLOB *lm_session_key) 
 {
+       struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
        NTSTATUS nt_status;
        DATA_BLOB session_key = data_blob(NULL, 0);
 
@@ -439,8 +419,8 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_ntlmssp_state *gensec_ntlm
        if (gensec_ntlmssp_state->doing_ntlm2) {
                if (user_session_key && user_session_key->data && user_session_key->length == 16) {
                        session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
-                       hmac_md5(user_session_key->data, gensec_ntlmssp_state->ntlm2.session_nonce, 
-                                sizeof(gensec_ntlmssp_state->ntlm2.session_nonce), session_key.data);
+                       hmac_md5(user_session_key->data, gensec_ntlmssp_state->crypt.ntlm2.session_nonce, 
+                                sizeof(gensec_ntlmssp_state->crypt.ntlm2.session_nonce), session_key.data);
                        DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
                        dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
                        
@@ -509,11 +489,11 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_ntlmssp_state *gensec_ntlm
                    || gensec_ntlmssp_state->encrypted_session_key.length != 16) {
                        data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
                        DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", 
-                                 gensec_ntlmssp_state->encrypted_session_key.length));
+                                 (unsigned)gensec_ntlmssp_state->encrypted_session_key.length));
                        return NT_STATUS_INVALID_PARAMETER;
                } else if (!session_key.data || session_key.length != 16) {
                        DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", 
-                                 session_key.length));
+                                 (unsigned)session_key.length));
                        gensec_ntlmssp_state->session_key = session_key;
                } else {
                        dump_data_pw("KEY_EXCH session key (enc):\n", 
@@ -532,10 +512,15 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_ntlmssp_state *gensec_ntlm
                gensec_ntlmssp_state->session_key = session_key;
        }
 
-       /* The server might need us to use a partial-strength session key */
-       ntlmssp_weaken_keys(gensec_ntlmssp_state);
+       /* keep the session key around on the new context */
+       talloc_steal(gensec_ntlmssp_state, session_key.data);
 
-       nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);
+       if ((gensec_security->want_features & GENSEC_FEATURE_SIGN)
+           || (gensec_security->want_features & GENSEC_FEATURE_SEAL)) {
+               nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);
+       } else {
+               nt_status = NT_STATUS_OK;
+       }
 
        data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
        
@@ -566,16 +551,22 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_ntlmssp_state *gensec_ntlm
 NTSTATUS ntlmssp_server_auth(struct gensec_security *gensec_security, 
                             TALLOC_CTX *out_mem_ctx, 
                             const DATA_BLOB in, DATA_BLOB *out) 
-{
-       struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+{      
+       struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
        DATA_BLOB user_session_key = data_blob(NULL, 0);
        DATA_BLOB lm_session_key = data_blob(NULL, 0);
        NTSTATUS nt_status;
 
+       TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
+       if (!mem_ctx) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
        /* zero the outbound NTLMSSP packet */
        *out = data_blob_talloc(out_mem_ctx, NULL, 0);
 
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(gensec_ntlmssp_state, in))) {
+               talloc_free(mem_ctx);
                return nt_status;
        }
 
@@ -588,15 +579,20 @@ NTSTATUS ntlmssp_server_auth(struct gensec_security *gensec_security,
 
        /* Finally, actually ask if the password is OK */
 
-       if (!NT_STATUS_IS_OK(nt_status = gensec_ntlmssp_state->check_password(gensec_ntlmssp_state, 
-                                                                      &user_session_key, &lm_session_key))) {
+       if (!NT_STATUS_IS_OK(nt_status = gensec_ntlmssp_state->check_password(gensec_ntlmssp_state, mem_ctx,
+                                                                             &user_session_key, &lm_session_key))) {
+               talloc_free(mem_ctx);
                return nt_status;
        }
        
-       if (gensec_ntlmssp_state->server_use_session_keys) {
-               return ntlmssp_server_postauth(gensec_ntlmssp_state, &user_session_key, &lm_session_key);
+       if (gensec_security->want_features
+           & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL|GENSEC_FEATURE_SESSION_KEY)) {
+               nt_status = ntlmssp_server_postauth(gensec_security, &user_session_key, &lm_session_key);
+               talloc_free(mem_ctx);
+               return nt_status;
        } else {
                gensec_ntlmssp_state->session_key = data_blob(NULL, 0);
+               talloc_free(mem_ctx);
                return NT_STATUS_OK;
        }
 }
@@ -611,8 +607,10 @@ static const uint8_t *auth_ntlmssp_get_challenge(const struct gensec_ntlmssp_sta
        NTSTATUS status;
        const uint8_t *chal;
 
-       status = auth_get_challenge(gensec_ntlmssp_state->auth_context, &chal);
+       status = gensec_ntlmssp_state->auth_context->get_challenge(gensec_ntlmssp_state->auth_context, &chal);
        if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n",
+                       nt_errstr(status)));
                return NULL;
        }
 
@@ -624,9 +622,9 @@ static const uint8_t *auth_ntlmssp_get_challenge(const struct gensec_ntlmssp_sta
  *
  * @return If the effective challenge used by the auth subsystem may be modified
  */
-static BOOL auth_ntlmssp_may_set_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
+static bool auth_ntlmssp_may_set_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
 {
-       return auth_challenge_may_be_modified(gensec_ntlmssp_state->auth_context);
+       return gensec_ntlmssp_state->auth_context->challenge_may_be_modified(gensec_ntlmssp_state->auth_context);
 }
 
 /**
@@ -645,7 +643,9 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct gensec_ntlmssp_state *gensec_n
 
        chal = challenge->data;
 
-       nt_status = auth_context_set_challenge(auth_context, chal, "NTLMSSP callback (NTLM2)");
+       nt_status = gensec_ntlmssp_state->auth_context->set_challenge(auth_context, 
+                                                                     chal, 
+                                                                     "NTLMSSP callback (NTLM2)");
 
        return nt_status;
 }
@@ -656,37 +656,56 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct gensec_ntlmssp_state *gensec_n
  * Return the session keys used on the connection.
  */
 
-static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 
+static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ntlmssp_state, 
+                                           TALLOC_CTX *mem_ctx, 
+                                           DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 
 {
-       struct auth_usersupplied_info *user_info = NULL;
        NTSTATUS nt_status;
+       struct auth_usersupplied_info *user_info = talloc(mem_ctx, struct auth_usersupplied_info);
+       if (!user_info) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
-       nt_status = make_user_info_map(gensec_ntlmssp_state, 
-                                      gensec_ntlmssp_state->user, 
-                                      gensec_ntlmssp_state->domain, 
-                                      gensec_ntlmssp_state->workstation, 
-                                      gensec_ntlmssp_state->lm_resp.data ? &gensec_ntlmssp_state->lm_resp : NULL, 
-                                      gensec_ntlmssp_state->nt_resp.data ? &gensec_ntlmssp_state->nt_resp : NULL, 
-                                      NULL, NULL, NULL, True,
-                                      &user_info);
-       NT_STATUS_NOT_OK_RETURN(nt_status);
-
-       nt_status = auth_check_password(gensec_ntlmssp_state->auth_context, gensec_ntlmssp_state,
-                                       user_info, &gensec_ntlmssp_state->server_info);
+       user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
+       user_info->flags = 0;
+       user_info->mapped_state = false;
+       user_info->client.account_name = gensec_ntlmssp_state->user;
+       user_info->client.domain_name = gensec_ntlmssp_state->domain;
+       user_info->workstation_name = gensec_ntlmssp_state->workstation;
+       user_info->remote_host = gensec_get_peer_addr(gensec_ntlmssp_state->gensec_security);
+
+       user_info->password_state = AUTH_PASSWORD_RESPONSE;
+       user_info->password.response.lanman = gensec_ntlmssp_state->lm_resp;
+       user_info->password.response.lanman.data = talloc_steal(user_info, gensec_ntlmssp_state->lm_resp.data);
+       user_info->password.response.nt = gensec_ntlmssp_state->nt_resp;
+       user_info->password.response.nt.data = talloc_steal(user_info, gensec_ntlmssp_state->nt_resp.data);
+
+       nt_status = gensec_ntlmssp_state->auth_context->check_password(gensec_ntlmssp_state->auth_context, 
+                                                                      mem_ctx,
+                                                                      user_info, 
+                                                                      &gensec_ntlmssp_state->server_info);
        talloc_free(user_info);
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
+       talloc_steal(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info);
+
        if (gensec_ntlmssp_state->server_info->user_session_key.length) {
-               DEBUG(10, ("Got NT session key of length %u\n", gensec_ntlmssp_state->server_info->user_session_key.length));
-               *user_session_key = data_blob_talloc(gensec_ntlmssp_state, 
-                                                  gensec_ntlmssp_state->server_info->user_session_key.data,
-                                                  gensec_ntlmssp_state->server_info->user_session_key.length);
+               DEBUG(10, ("Got NT session key of length %u\n", 
+                          (unsigned)gensec_ntlmssp_state->server_info->user_session_key.length));
+               if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->user_session_key.data)) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               *user_session_key = gensec_ntlmssp_state->server_info->user_session_key;
        }
        if (gensec_ntlmssp_state->server_info->lm_session_key.length) {
-               DEBUG(10, ("Got LM session key of length %u\n", gensec_ntlmssp_state->server_info->lm_session_key.length));
-               *lm_session_key = data_blob_talloc(gensec_ntlmssp_state, 
-                                                  gensec_ntlmssp_state->server_info->lm_session_key.data,
-                                                  gensec_ntlmssp_state->server_info->lm_session_key.length);
+               DEBUG(10, ("Got LM session key of length %u\n", 
+                          (unsigned)gensec_ntlmssp_state->server_info->lm_session_key.length));
+               if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->lm_session_key.data)) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               *lm_session_key = gensec_ntlmssp_state->server_info->lm_session_key;
        }
        return nt_status;
 }
@@ -705,9 +724,9 @@ NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
                                     struct auth_session_info **session_info) 
 {
        NTSTATUS nt_status;
-       struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+       struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
 
-       nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info, session_info);
+       nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_security->event_ctx, gensec_security->settings->lp_ctx, gensec_ntlmssp_state->server_info, session_info);
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
        (*session_info)->session_key = data_blob_talloc(*session_info, 
@@ -729,40 +748,46 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
        nt_status = gensec_ntlmssp_start(gensec_security);
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
-       gensec_ntlmssp_state = gensec_security->private_data;
+       gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
 
        gensec_ntlmssp_state->role = NTLMSSP_SERVER;
 
-       gensec_ntlmssp_state->get_challenge = get_challenge;
-       gensec_ntlmssp_state->set_challenge = set_challenge;
-       gensec_ntlmssp_state->may_set_challenge = may_set_challenge;
-
        gensec_ntlmssp_state->workstation = NULL;
-       gensec_ntlmssp_state->server_name = lp_netbios_name();
+       gensec_ntlmssp_state->server_name = lp_netbios_name(gensec_security->settings->lp_ctx);
 
-       gensec_ntlmssp_state->get_domain = lp_workgroup;
-       gensec_ntlmssp_state->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
+       gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx);
 
        gensec_ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
 
-       gensec_ntlmssp_state->allow_lm_key = (lp_lanman_auth() 
-                                         && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False));
+       gensec_ntlmssp_state->allow_lm_key = (lp_lanman_auth(gensec_security->settings->lp_ctx
+                                         && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));
 
-       gensec_ntlmssp_state->server_use_session_keys = True;
-       gensec_ntlmssp_state->server_multiple_authentications = False;
+       gensec_ntlmssp_state->server_multiple_authentications = false;
        
        gensec_ntlmssp_state->neg_flags = 
-               NTLMSSP_NEGOTIATE_NTLM;
+               NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_UNKNOWN_02000000;
+
+       gensec_ntlmssp_state->lm_resp = data_blob(NULL, 0);
+       gensec_ntlmssp_state->nt_resp = data_blob(NULL, 0);
+       gensec_ntlmssp_state->encrypted_session_key = data_blob(NULL, 0);
 
-       if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) {
+       if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
                gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;               
        }
 
-       if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) {
+       if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
+               gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;                
+       }
+
+       if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
                gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;          
        }
 
-       if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) {
+       if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
+               gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;               
+       }
+
+       if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
                gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;             
        }
 
@@ -773,14 +798,13 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
                gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
        }
 
-       nt_status = auth_context_create(gensec_ntlmssp_state, lp_auth_methods(), &gensec_ntlmssp_state->auth_context);
-       NT_STATUS_NOT_OK_RETURN(nt_status);
+       gensec_ntlmssp_state->auth_context = gensec_security->auth_context;
 
        gensec_ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
        gensec_ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
        gensec_ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
        gensec_ntlmssp_state->check_password = auth_ntlmssp_check_password;
-       gensec_ntlmssp_state->server_role = lp_server_role();
+       gensec_ntlmssp_state->server_role = lp_server_role(gensec_security->settings->lp_ctx);
 
        return NT_STATUS_OK;
 }