Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/auth/ntlmssp/ntlmssp_server.c

    r414 r745  
    2424#include "includes.h"
    2525#include "system/network.h"
     26
    2627#include "auth/ntlmssp/ntlmssp.h"
    27 #include "../librpc/gen_ndr/ntlmssp.h"
     28#include "../librpc/gen_ndr/ndr_ntlmssp.h"
     29#include "../libcli/auth/ntlmssp_ndr.h"
     30#include "../libcli/auth/ntlmssp_private.h"
    2831#include "../libcli/auth/libcli_auth.h"
    2932#include "../lib/crypto/crypto.h"
    3033#include "auth/gensec/gensec.h"
     34
    3135#include "auth/auth.h"
    32 #include "auth/ntlm/auth_proto.h"
    3336#include "param/param.h"
    34 #include "auth/session_proto.h"
    35 
    36 /**
    37  * Set a username on an NTLMSSP context - ensures it is talloc()ed
    38  *
    39  */
    40 
    41 static NTSTATUS ntlmssp_set_username(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *user)
    42 {
    43         if (!user) {
    44                 /* it should be at least "" */
    45                 DEBUG(1, ("NTLMSSP failed to set username - cannot accept NULL username\n"));
    46                 return NT_STATUS_INVALID_PARAMETER;
    47         }
    48         gensec_ntlmssp_state->user = talloc_strdup(gensec_ntlmssp_state, user);
    49         if (!gensec_ntlmssp_state->user) {
    50                 return NT_STATUS_NO_MEMORY;
    51         }
    52         return NT_STATUS_OK;
    53 }
    54 
    55 /**
    56  * Set a domain on an NTLMSSP context - ensures it is talloc()ed
    57  *
    58  */
    59 static NTSTATUS ntlmssp_set_domain(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *domain)
    60 {
    61         gensec_ntlmssp_state->domain = talloc_strdup(gensec_ntlmssp_state, domain);
    62         if (!gensec_ntlmssp_state->domain) {
    63                 return NT_STATUS_NO_MEMORY;
    64         }
    65         return NT_STATUS_OK;
    66 }
    67 
    68 /**
    69  * Set a workstation on an NTLMSSP context - ensures it is talloc()ed
    70  *
    71  */
    72 static NTSTATUS ntlmssp_set_workstation(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *workstation)
    73 {
    74         gensec_ntlmssp_state->workstation = talloc_strdup(gensec_ntlmssp_state, workstation);
    75         if (!gensec_ntlmssp_state->workstation) {
    76                 return NT_STATUS_NO_MEMORY;
    77         }
    78         return NT_STATUS_OK;
    79 }
    80 
    81 /**
    82  * Determine correct target name flags for reply, given server role
    83  * and negotiated flags
    84  *
    85  * @param gensec_ntlmssp_state NTLMSSP State
    86  * @param neg_flags The flags from the packet
    87  * @param chal_flags The flags to be set in the reply packet
    88  * @return The 'target name' string.
    89  */
    90 
    91 static const char *ntlmssp_target_name(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    92                                        uint32_t neg_flags, uint32_t *chal_flags)
    93 {
    94         if (neg_flags & NTLMSSP_REQUEST_TARGET) {
    95                 *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
    96                 *chal_flags |= NTLMSSP_REQUEST_TARGET;
    97                 if (gensec_ntlmssp_state->server_role == ROLE_STANDALONE) {
    98                         *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
    99                         return gensec_ntlmssp_state->server_name;
    100                 } else {
    101                         *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
    102                         return gensec_ntlmssp_state->domain;
    103                 };
    104         } else {
    105                 return "";
    106         }
    107 }
    108 
    109 
    110 
    111 /**
    112  * Next state function for the Negotiate packet
    113  *
     37
     38/**
     39 * Next state function for the Negotiate packet (GENSEC wrapper)
     40 *
    11441 * @param gensec_security GENSEC state
    11542 * @param out_mem_ctx Memory context for *out
    11643 * @param in The request, as a DATA_BLOB.  reply.data must be NULL
    11744 * @param out The reply, as an allocated DATA_BLOB, caller to free.
    118  * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
    119  */
    120 
    121 NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security,
    122                                   TALLOC_CTX *out_mem_ctx,
    123                                   const DATA_BLOB in, DATA_BLOB *out)
    124 {
    125         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    126         DATA_BLOB struct_blob;
    127         uint32_t neg_flags = 0;
    128         uint32_t ntlmssp_command, chal_flags;
    129         const uint8_t *cryptkey;
    130         const char *target_name;
    131 
    132         /* parse the NTLMSSP packet */
    133 #if 0
    134         file_save("ntlmssp_negotiate.dat", request.data, request.length);
    135 #endif
    136 
    137         if (in.length) {
    138                 if ((in.length < 16) || !msrpc_parse(out_mem_ctx,
    139                                                          &in, "Cdd",
    140                                                          "NTLMSSP",
    141                                                          &ntlmssp_command,
    142                                                          &neg_flags)) {
    143                         DEBUG(1, ("ntlmssp_server_negotiate: failed to parse "
    144                                 "NTLMSSP Negotiate of length %u:\n",
    145                                 (unsigned int)in.length ));
    146                         dump_data(2, in.data, in.length);
    147                         return NT_STATUS_INVALID_PARAMETER;
    148                 }
    149                 debug_ntlmssp_flags(neg_flags);
    150         }
    151        
    152         ntlmssp_handle_neg_flags(gensec_ntlmssp_state, neg_flags, gensec_ntlmssp_state->allow_lm_key);
    153 
    154         /* Ask our caller what challenge they would like in the packet */
    155         cryptkey = gensec_ntlmssp_state->get_challenge(gensec_ntlmssp_state);
    156         if (!cryptkey) {
    157                 DEBUG(1, ("ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
    158                 return NT_STATUS_INTERNAL_ERROR;
    159         }
    160 
    161         /* Check if we may set the challenge */
    162         if (!gensec_ntlmssp_state->may_set_challenge(gensec_ntlmssp_state)) {
    163                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    164         }
    165 
    166         /* The flags we send back are not just the negotiated flags,
    167          * they are also 'what is in this packet'.  Therfore, we
    168          * operate on 'chal_flags' from here on
    169          */
    170 
    171         chal_flags = gensec_ntlmssp_state->neg_flags;
    172 
    173         /* get the right name to fill in as 'target' */
    174         target_name = ntlmssp_target_name(gensec_ntlmssp_state,
    175                                           neg_flags, &chal_flags);
    176         if (target_name == NULL)
     45 * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
     46 */
     47
     48NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security,
     49                                         TALLOC_CTX *out_mem_ctx,
     50                                         const DATA_BLOB request, DATA_BLOB *reply)
     51{
     52        struct gensec_ntlmssp_context *gensec_ntlmssp =
     53                talloc_get_type_abort(gensec_security->private_data,
     54                                      struct gensec_ntlmssp_context);
     55        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     56        return ntlmssp_server_negotiate(ntlmssp_state, out_mem_ctx, request, reply);
     57}
     58
     59/**
     60 * Next state function for the Authenticate packet (GENSEC wrapper)
     61 *
     62 * @param gensec_security GENSEC state
     63 * @param out_mem_ctx Memory context for *out
     64 * @param in The request, as a DATA_BLOB.  reply.data must be NULL
     65 * @param out The reply, as an allocated DATA_BLOB, caller to free.
     66 * @return Errors or NT_STATUS_OK if authentication sucessful
     67 */
     68
     69NTSTATUS gensec_ntlmssp_server_auth(struct gensec_security *gensec_security,
     70                                    TALLOC_CTX *out_mem_ctx,
     71                                    const DATA_BLOB in, DATA_BLOB *out)
     72{
     73        struct gensec_ntlmssp_context *gensec_ntlmssp =
     74                talloc_get_type_abort(gensec_security->private_data,
     75                                      struct gensec_ntlmssp_context);
     76        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     77        return ntlmssp_server_auth(ntlmssp_state, out_mem_ctx, in, out);
     78}
     79
     80/**
     81 * Return the challenge as determined by the authentication subsystem
     82 * @return an 8 byte random challenge
     83 */
     84
     85static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
     86                                           uint8_t chal[8])
     87{
     88        struct gensec_ntlmssp_context *gensec_ntlmssp =
     89                talloc_get_type_abort(ntlmssp_state->callback_private,
     90                                      struct gensec_ntlmssp_context);
     91        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     92        NTSTATUS status;
     93
     94        status = auth_context->get_challenge(auth_context, chal);
     95        if (!NT_STATUS_IS_OK(status)) {
     96                DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n",
     97                        nt_errstr(status)));
     98                return status;
     99        }
     100
     101        return NT_STATUS_OK;
     102}
     103
     104/**
     105 * Some authentication methods 'fix' the challenge, so we may not be able to set it
     106 *
     107 * @return If the effective challenge used by the auth subsystem may be modified
     108 */
     109static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
     110{
     111        struct gensec_ntlmssp_context *gensec_ntlmssp =
     112                talloc_get_type_abort(ntlmssp_state->callback_private,
     113                                      struct gensec_ntlmssp_context);
     114        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     115
     116        return auth_context->challenge_may_be_modified(auth_context);
     117}
     118
     119/**
     120 * NTLM2 authentication modifies the effective challenge,
     121 * @param challenge The new challenge value
     122 */
     123static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
     124{
     125        struct gensec_ntlmssp_context *gensec_ntlmssp =
     126                talloc_get_type_abort(ntlmssp_state->callback_private,
     127                                      struct gensec_ntlmssp_context);
     128        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     129        NTSTATUS nt_status;
     130        const uint8_t *chal;
     131
     132        if (challenge->length != 8) {
    177133                return NT_STATUS_INVALID_PARAMETER;
    178 
    179         gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8);
    180         gensec_ntlmssp_state->internal_chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8);
    181 
    182         /* This creates the 'blob' of names that appears at the end of the packet */
    183         if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
     134        }
     135
     136        chal = challenge->data;
     137
     138        nt_status = auth_context->set_challenge(auth_context,
     139                                                chal,
     140                                                "NTLMSSP callback (NTLM2)");
     141
     142        return nt_status;
     143}
     144
     145/**
     146 * Check the password on an NTLMSSP login. 
     147 *
     148 * Return the session keys used on the connection.
     149 */
     150
     151static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state,
     152                                            TALLOC_CTX *mem_ctx,
     153                                            DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
     154{
     155        struct gensec_ntlmssp_context *gensec_ntlmssp =
     156                talloc_get_type_abort(ntlmssp_state->callback_private,
     157                                      struct gensec_ntlmssp_context);
     158        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     159        NTSTATUS nt_status;
     160        struct auth_usersupplied_info *user_info;
     161
     162        user_info = talloc_zero(ntlmssp_state, struct auth_usersupplied_info);
     163        if (!user_info) {
     164                return NT_STATUS_NO_MEMORY;
     165        }
     166
     167        user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
     168        user_info->flags = 0;
     169        user_info->mapped_state = false;
     170        user_info->client.account_name = ntlmssp_state->user;
     171        user_info->client.domain_name = ntlmssp_state->domain;
     172        user_info->workstation_name = ntlmssp_state->client.netbios_name;
     173        user_info->remote_host = gensec_get_remote_address(gensec_ntlmssp->gensec_security);
     174
     175        user_info->password_state = AUTH_PASSWORD_RESPONSE;
     176        user_info->password.response.lanman = ntlmssp_state->lm_resp;
     177        user_info->password.response.lanman.data = talloc_steal(user_info, ntlmssp_state->lm_resp.data);
     178        user_info->password.response.nt = ntlmssp_state->nt_resp;
     179        user_info->password.response.nt.data = talloc_steal(user_info, ntlmssp_state->nt_resp.data);
     180
     181        nt_status = auth_context->check_password(auth_context,
     182                                                 gensec_ntlmssp,
     183                                                 user_info,
     184                                                 &gensec_ntlmssp->user_info_dc);
     185        talloc_free(user_info);
     186        NT_STATUS_NOT_OK_RETURN(nt_status);
     187
     188        if (gensec_ntlmssp->user_info_dc->user_session_key.length) {
     189                DEBUG(10, ("Got NT session key of length %u\n",
     190                           (unsigned)gensec_ntlmssp->user_info_dc->user_session_key.length));
     191                *user_session_key = gensec_ntlmssp->user_info_dc->user_session_key;
     192                talloc_steal(mem_ctx, user_session_key->data);
     193                gensec_ntlmssp->user_info_dc->user_session_key = data_blob_null;
     194        }
     195        if (gensec_ntlmssp->user_info_dc->lm_session_key.length) {
     196                DEBUG(10, ("Got LM session key of length %u\n",
     197                           (unsigned)gensec_ntlmssp->user_info_dc->lm_session_key.length));
     198                *lm_session_key = gensec_ntlmssp->user_info_dc->lm_session_key;
     199                talloc_steal(mem_ctx, lm_session_key->data);
     200                gensec_ntlmssp->user_info_dc->lm_session_key = data_blob_null;
     201        }
     202        return nt_status;
     203}
     204
     205/**
     206 * Return the credentials of a logged on user, including session keys
     207 * etc.
     208 *
     209 * Only valid after a successful authentication
     210 *
     211 * May only be called once per authentication.
     212 *
     213 */
     214
     215NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
     216                                     struct auth_session_info **session_info)
     217{
     218        NTSTATUS nt_status;
     219        struct gensec_ntlmssp_context *gensec_ntlmssp =
     220                talloc_get_type_abort(gensec_security->private_data,
     221                                      struct gensec_ntlmssp_context);
     222        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     223
     224        nt_status = gensec_generate_session_info(ntlmssp_state,
     225                                                 gensec_security,
     226                                                 gensec_ntlmssp->user_info_dc,
     227                                                 session_info);
     228        NT_STATUS_NOT_OK_RETURN(nt_status);
     229
     230        (*session_info)->session_key = data_blob_talloc(*session_info,
     231                                                        ntlmssp_state->session_key.data,
     232                                                        ntlmssp_state->session_key.length);
     233
     234        return NT_STATUS_OK;
     235}
     236
     237/**
     238 * Start NTLMSSP on the server side
     239 *
     240 */
     241NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
     242{
     243        NTSTATUS nt_status;
     244        struct ntlmssp_state *ntlmssp_state;
     245        struct gensec_ntlmssp_context *gensec_ntlmssp;
     246
     247        nt_status = gensec_ntlmssp_start(gensec_security);
     248        NT_STATUS_NOT_OK_RETURN(nt_status);
     249
     250        gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
     251                                               struct gensec_ntlmssp_context);
     252        ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     253
     254        ntlmssp_state->role = NTLMSSP_SERVER;
     255
     256        ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
     257
     258        ntlmssp_state->allow_lm_key = (lpcfg_lanman_auth(gensec_security->settings->lp_ctx)
     259                                          && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));
     260
     261        ntlmssp_state->neg_flags =
     262                NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;
     263
     264        ntlmssp_state->lm_resp = data_blob(NULL, 0);
     265        ntlmssp_state->nt_resp = data_blob(NULL, 0);
     266
     267        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
     268                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
     269        }
     270
     271        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
     272                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
     273        }
     274
     275        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
     276                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
     277        }
     278
     279        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
     280                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
     281        }
     282
     283        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
     284                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
     285        }
     286
     287        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
     288                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     289        }
     290        if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
     291                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
     292        }
     293
     294        gensec_ntlmssp->auth_context = gensec_security->auth_context;
     295
     296        ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
     297        ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
     298        ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
     299        ntlmssp_state->check_password = auth_ntlmssp_check_password;
     300        if (lpcfg_server_role(gensec_security->settings->lp_ctx) == ROLE_STANDALONE) {
     301                ntlmssp_state->server.is_standalone = true;
     302        } else {
     303                ntlmssp_state->server.is_standalone = false;
     304        }
     305
     306        ntlmssp_state->server.netbios_name = lpcfg_netbios_name(gensec_security->settings->lp_ctx);
     307
     308        ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
     309
     310        {
    184311                char dnsdomname[MAXHOSTNAMELEN], dnsname[MAXHOSTNAMELEN];
    185                 const char *target_name_dns = "";
    186312
    187313                /* Find out the DNS domain name */
    188314                dnsdomname[0] = '\0';
    189                 safe_strcpy(dnsdomname, lp_realm(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1);
    190                 strlower_m(dnsdomname);
     315                safe_strcpy(dnsdomname, lpcfg_dnsdomain(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1);
    191316
    192317                /* Find out the DNS host name */
    193                 safe_strcpy(dnsname, gensec_ntlmssp_state->server_name, sizeof(dnsname) - 1);
     318                safe_strcpy(dnsname, _name, sizeof(dnsname) - 1);
    194319                if (dnsdomname[0] != '\0') {
    195320                        safe_strcat(dnsname, ".", sizeof(dnsname) - 1);
     
    198323                strlower_m(dnsname);
    199324
    200                 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
    201                         target_name_dns = dnsdomname;
    202                 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
    203                         target_name_dns = dnsname;
    204                 }
    205 
    206                 msrpc_gen(out_mem_ctx,
    207                           &struct_blob, "aaaaa",
    208                           MsvAvNbDomainName, target_name,
    209                           MsvAvNbComputerName, gensec_ntlmssp_state->server_name,
    210                           MsvAvDnsDomainName, dnsdomname,
    211                           MsvAvDnsComputerName, dnsname,
    212                           MsvAvEOL, "");
    213         } else {
    214                 struct_blob = data_blob(NULL, 0);
    215         }
    216 
    217         {
    218                 /* Marshal the packet in the right format, be it unicode or ASCII */
    219                 const char *gen_string;
    220                 if (gensec_ntlmssp_state->unicode) {
    221                         gen_string = "CdUdbddB";
    222                 } else {
    223                         gen_string = "CdAdbddB";
    224                 }
    225                
    226                 msrpc_gen(out_mem_ctx,
    227                           out, gen_string,
    228                           "NTLMSSP",
    229                           NTLMSSP_CHALLENGE,
    230                           target_name,
    231                           chal_flags,
    232                           cryptkey, 8,
    233                           0, 0,
    234                           struct_blob.data, struct_blob.length);
    235         }
    236                
    237         gensec_ntlmssp_state->expected_state = NTLMSSP_AUTH;
    238 
    239         return NT_STATUS_MORE_PROCESSING_REQUIRED;
    240 }
    241 
    242 /**
    243  * Next state function for the Authenticate packet
    244  *
    245  * @param gensec_ntlmssp_state NTLMSSP State
    246  * @param request The request, as a DATA_BLOB
    247  * @return Errors or NT_STATUS_OK.
    248  */
    249 
    250 static NTSTATUS ntlmssp_server_preauth(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    251                                        const DATA_BLOB request)
    252 {
    253         uint32_t ntlmssp_command, auth_flags;
    254         NTSTATUS nt_status;
    255 
    256         uint8_t session_nonce_hash[16];
    257 
    258         const char *parse_string;
    259         char *domain = NULL;
    260         char *user = NULL;
    261         char *workstation = NULL;
    262 
    263 #if 0
    264         file_save("ntlmssp_auth.dat", request.data, request.length);
    265 #endif
    266 
    267         if (gensec_ntlmssp_state->unicode) {
    268                 parse_string = "CdBBUUUBd";
    269         } else {
    270                 parse_string = "CdBBAAABd";
    271         }
    272 
    273         /* zero these out */
    274         data_blob_free(&gensec_ntlmssp_state->lm_resp);
    275         data_blob_free(&gensec_ntlmssp_state->nt_resp);
    276         data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    277 
    278         gensec_ntlmssp_state->user = NULL;
    279         gensec_ntlmssp_state->domain = NULL;
    280         gensec_ntlmssp_state->workstation = NULL;
    281 
    282         /* now the NTLMSSP encoded auth hashes */
    283         if (!msrpc_parse(gensec_ntlmssp_state,
    284                          &request, parse_string,
    285                          "NTLMSSP",
    286                          &ntlmssp_command,
    287                          &gensec_ntlmssp_state->lm_resp,
    288                          &gensec_ntlmssp_state->nt_resp,
    289                          &domain,
    290                          &user,
    291                          &workstation,
    292                          &gensec_ntlmssp_state->encrypted_session_key,
    293                          &auth_flags)) {
    294                 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
    295                 dump_data(10, request.data, request.length);
    296 
    297                 /* zero this out */
    298                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    299                 auth_flags = 0;
    300                
    301                 /* Try again with a shorter string (Win9X truncates this packet) */
    302                 if (gensec_ntlmssp_state->unicode) {
    303                         parse_string = "CdBBUUU";
    304                 } else {
    305                         parse_string = "CdBBAAA";
    306                 }
    307 
    308                 /* now the NTLMSSP encoded auth hashes */
    309                 if (!msrpc_parse(gensec_ntlmssp_state,
    310                                  &request, parse_string,
    311                                  "NTLMSSP",
    312                                  &ntlmssp_command,
    313                                  &gensec_ntlmssp_state->lm_resp,
    314                                  &gensec_ntlmssp_state->nt_resp,
    315                                  &domain,
    316                                  &user,
    317                                  &workstation)) {
    318                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
    319                         dump_data(2, request.data, request.length);
    320 
    321                         return NT_STATUS_INVALID_PARAMETER;
    322                 }
    323         }
    324 
    325         if (auth_flags)
    326                 ntlmssp_handle_neg_flags(gensec_ntlmssp_state, auth_flags, gensec_ntlmssp_state->allow_lm_key);
    327 
    328         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(gensec_ntlmssp_state, domain))) {
    329                 /* zero this out */
    330                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    331                 return nt_status;
    332         }
    333 
    334         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(gensec_ntlmssp_state, user))) {
    335                 /* zero this out */
    336                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    337                 return nt_status;
    338         }
    339 
    340         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state, workstation))) {
    341                 /* zero this out */
    342                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    343                 return nt_status;
    344         }
    345 
    346         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
    347                  gensec_ntlmssp_state->user, gensec_ntlmssp_state->domain, gensec_ntlmssp_state->workstation, (unsigned long)gensec_ntlmssp_state->lm_resp.length, (unsigned long)gensec_ntlmssp_state->nt_resp.length));
    348 
    349 #if 0
    350         file_save("nthash1.dat",  &gensec_ntlmssp_state->nt_resp.data,  &gensec_ntlmssp_state->nt_resp.length);
    351         file_save("lmhash1.dat",  &gensec_ntlmssp_state->lm_resp.data,  &gensec_ntlmssp_state->lm_resp.length);
    352 #endif
    353 
    354         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
    355            client challenge
    356        
    357            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
    358         */
    359         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    360                 if (gensec_ntlmssp_state->nt_resp.length == 24 && gensec_ntlmssp_state->lm_resp.length == 24) {
    361                         struct MD5Context md5_session_nonce_ctx;
    362                         SMB_ASSERT(gensec_ntlmssp_state->internal_chal.data
    363                                    && gensec_ntlmssp_state->internal_chal.length == 8);
    364                        
    365                         gensec_ntlmssp_state->doing_ntlm2 = true;
    366 
    367                         memcpy(gensec_ntlmssp_state->crypt.ntlm2.session_nonce, gensec_ntlmssp_state->internal_chal.data, 8);
    368                         memcpy(&gensec_ntlmssp_state->crypt.ntlm2.session_nonce[8], gensec_ntlmssp_state->lm_resp.data, 8);
    369                        
    370                         MD5Init(&md5_session_nonce_ctx);
    371                         MD5Update(&md5_session_nonce_ctx, gensec_ntlmssp_state->crypt.ntlm2.session_nonce, 16);
    372                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
    373                        
    374                         gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state,
    375                                                                session_nonce_hash, 8);
    376 
    377                         /* LM response is no longer useful, zero it out */
    378                         data_blob_free(&gensec_ntlmssp_state->lm_resp);
    379 
    380                         /* We changed the effective challenge - set it */
    381                         if (!NT_STATUS_IS_OK(nt_status =
    382                                              gensec_ntlmssp_state->set_challenge(gensec_ntlmssp_state,
    383                                                                                  &gensec_ntlmssp_state->chal))) {
    384                                 /* zero this out */
    385                                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    386                                 return nt_status;
    387                         }
    388 
    389                         /* LM Key is incompatible... */
    390                         gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    391                 }
    392         }
     325                ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state,
     326                                                                      dnsname);
     327                NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name);
     328
     329                ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state,
     330                                                                        dnsdomname);
     331                NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain);
     332        }
     333
    393334        return NT_STATUS_OK;
    394335}
    395336
    396 /**
    397  * Next state function for the Authenticate packet
    398  * (after authentication - figures out the session keys etc)
    399  *
    400  * @param gensec_ntlmssp_state NTLMSSP State
    401  * @return Errors or NT_STATUS_OK.
    402  */
    403 
    404 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
    405                                         DATA_BLOB *user_session_key,
    406                                         DATA_BLOB *lm_session_key)
    407 {
    408         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    409         NTSTATUS nt_status;
    410         DATA_BLOB session_key = data_blob(NULL, 0);
    411 
    412         if (user_session_key)
    413                 dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length);
    414 
    415         if (lm_session_key)
    416                 dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length);
    417 
    418         /* Handle the different session key derivation for NTLM2 */
    419         if (gensec_ntlmssp_state->doing_ntlm2) {
    420                 if (user_session_key && user_session_key->data && user_session_key->length == 16) {
    421                         session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
    422                         hmac_md5(user_session_key->data, gensec_ntlmssp_state->crypt.ntlm2.session_nonce,
    423                                  sizeof(gensec_ntlmssp_state->crypt.ntlm2.session_nonce), session_key.data);
    424                         DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
    425                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
    426                        
    427                 } else {
    428                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
    429                         session_key = data_blob(NULL, 0);
    430                 }
    431         } else if ((gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
    432                 /* Ensure we can never get here on NTLMv2 */
    433                 && (gensec_ntlmssp_state->nt_resp.length == 0 || gensec_ntlmssp_state->nt_resp.length == 24)) {
    434 
    435                 if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
    436                         if (gensec_ntlmssp_state->lm_resp.data && gensec_ntlmssp_state->lm_resp.length == 24) {
    437                                 session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
    438                                 SMBsesskeygen_lm_sess_key(lm_session_key->data, gensec_ntlmssp_state->lm_resp.data,
    439                                                           session_key.data);
    440                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
    441                                 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
    442                         } else {
    443                                
    444                                 /* When there is no LM response, just use zeros */
    445                                 static const uint8_t zeros[24];
    446                                 session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
    447                                 SMBsesskeygen_lm_sess_key(zeros, zeros,
    448                                                           session_key.data);
    449                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
    450                                 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
    451                         }
    452                 } else {
    453                         /* LM Key not selected */
    454                         gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    455 
    456                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
    457                         session_key = data_blob(NULL, 0);
    458                 }
    459 
    460         } else if (user_session_key && user_session_key->data) {
    461                 session_key = data_blob_talloc(gensec_ntlmssp_state, user_session_key->data, user_session_key->length);
    462                 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
    463                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
    464 
    465                 /* LM Key not selected */
    466                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    467 
    468         } else if (lm_session_key && lm_session_key->data) {
    469                 /* Very weird to have LM key, but no user session key, but anyway.. */
    470                 session_key = data_blob_talloc(gensec_ntlmssp_state, lm_session_key->data, lm_session_key->length);
    471                 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
    472                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
    473 
    474                 /* LM Key not selected */
    475                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    476 
    477         } else {
    478                 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
    479                 session_key = data_blob(NULL, 0);
    480 
    481                 /* LM Key not selected */
    482                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    483         }
    484 
    485         /* With KEY_EXCH, the client supplies the proposed session key,
    486            but encrypts it with the long-term key */
    487         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    488                 if (!gensec_ntlmssp_state->encrypted_session_key.data
    489                     || gensec_ntlmssp_state->encrypted_session_key.length != 16) {
    490                         data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    491                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
    492                                   (unsigned)gensec_ntlmssp_state->encrypted_session_key.length));
    493                         return NT_STATUS_INVALID_PARAMETER;
    494                 } else if (!session_key.data || session_key.length != 16) {
    495                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
    496                                   (unsigned)session_key.length));
    497                         gensec_ntlmssp_state->session_key = session_key;
    498                 } else {
    499                         dump_data_pw("KEY_EXCH session key (enc):\n",
    500                                      gensec_ntlmssp_state->encrypted_session_key.data,
    501                                      gensec_ntlmssp_state->encrypted_session_key.length);
    502                         arcfour_crypt(gensec_ntlmssp_state->encrypted_session_key.data,
    503                                       session_key.data,
    504                                       gensec_ntlmssp_state->encrypted_session_key.length);
    505                         gensec_ntlmssp_state->session_key = data_blob_talloc(gensec_ntlmssp_state,
    506                                                                       gensec_ntlmssp_state->encrypted_session_key.data,
    507                                                                       gensec_ntlmssp_state->encrypted_session_key.length);
    508                         dump_data_pw("KEY_EXCH session key:\n", gensec_ntlmssp_state->encrypted_session_key.data,
    509                                      gensec_ntlmssp_state->encrypted_session_key.length);
    510                         talloc_free(session_key.data);
    511                 }
    512         } else {
    513                 gensec_ntlmssp_state->session_key = session_key;
    514         }
    515 
    516         if ((gensec_security->want_features & GENSEC_FEATURE_SIGN)
    517             || (gensec_security->want_features & GENSEC_FEATURE_SEAL)) {
    518                 nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);
    519         } else {
    520                 nt_status = NT_STATUS_OK;
    521         }
    522 
    523         data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    524        
    525         /* allow arbitarily many authentications, but watch that this will cause a
    526            memory leak, until the gensec_ntlmssp_state is shutdown
    527         */
    528 
    529         if (gensec_ntlmssp_state->server_multiple_authentications) {
    530                 gensec_ntlmssp_state->expected_state = NTLMSSP_AUTH;
    531         } else {
    532                 gensec_ntlmssp_state->expected_state = NTLMSSP_DONE;
    533         }
    534 
    535         return nt_status;
    536 }
    537 
    538 
    539 /**
    540  * Next state function for the Authenticate packet
    541  *
    542  * @param gensec_security GENSEC state
    543  * @param out_mem_ctx Memory context for *out
    544  * @param in The request, as a DATA_BLOB.  reply.data must be NULL
    545  * @param out The reply, as an allocated DATA_BLOB, caller to free.
    546  * @return Errors or NT_STATUS_OK if authentication sucessful
    547  */
    548 
    549 NTSTATUS ntlmssp_server_auth(struct gensec_security *gensec_security,
    550                              TALLOC_CTX *out_mem_ctx,
    551                              const DATA_BLOB in, DATA_BLOB *out)
    552 {       
    553         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    554         DATA_BLOB user_session_key = data_blob(NULL, 0);
    555         DATA_BLOB lm_session_key = data_blob(NULL, 0);
    556         NTSTATUS nt_status;
    557 
    558         TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
    559         if (!mem_ctx) {
    560                 return NT_STATUS_NO_MEMORY;
    561         }
    562 
    563         /* zero the outbound NTLMSSP packet */
    564         *out = data_blob_talloc(out_mem_ctx, NULL, 0);
    565 
    566         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(gensec_ntlmssp_state, in))) {
    567                 talloc_free(mem_ctx);
    568                 return nt_status;
    569         }
    570 
    571         /*
    572          * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
    573          * is required (by "ntlm auth = no" and "lm auth = no" being set in the
    574          * smb.conf file) and no NTLMv2 response was sent then the password check
    575          * will fail here. JRA.
    576          */
    577 
    578         /* Finally, actually ask if the password is OK */
    579 
    580         if (!NT_STATUS_IS_OK(nt_status = gensec_ntlmssp_state->check_password(gensec_ntlmssp_state, mem_ctx,
    581                                                                               &user_session_key, &lm_session_key))) {
    582                 talloc_free(mem_ctx);
    583                 return nt_status;
    584         }
    585        
    586         if (gensec_security->want_features
    587             & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL|GENSEC_FEATURE_SESSION_KEY)) {
    588                 nt_status = ntlmssp_server_postauth(gensec_security, &user_session_key, &lm_session_key);
    589                 talloc_free(mem_ctx);
    590                 return nt_status;
    591         } else {
    592                 gensec_ntlmssp_state->session_key = data_blob(NULL, 0);
    593                 talloc_free(mem_ctx);
    594                 return NT_STATUS_OK;
    595         }
    596 }
    597 
    598 /**
    599  * Return the challenge as determined by the authentication subsystem
    600  * @return an 8 byte random challenge
    601  */
    602 
    603 static const uint8_t *auth_ntlmssp_get_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
    604 {
    605         NTSTATUS status;
    606         const uint8_t *chal;
    607 
    608         status = gensec_ntlmssp_state->auth_context->get_challenge(gensec_ntlmssp_state->auth_context, &chal);
    609         if (!NT_STATUS_IS_OK(status)) {
    610                 DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n",
    611                         nt_errstr(status)));
    612                 return NULL;
    613         }
    614 
    615         return chal;
    616 }
    617 
    618 /**
    619  * Some authentication methods 'fix' the challenge, so we may not be able to set it
    620  *
    621  * @return If the effective challenge used by the auth subsystem may be modified
    622  */
    623 static bool auth_ntlmssp_may_set_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
    624 {
    625         return gensec_ntlmssp_state->auth_context->challenge_may_be_modified(gensec_ntlmssp_state->auth_context);
    626 }
    627 
    628 /**
    629  * NTLM2 authentication modifies the effective challenge,
    630  * @param challenge The new challenge value
    631  */
    632 static NTSTATUS auth_ntlmssp_set_challenge(struct gensec_ntlmssp_state *gensec_ntlmssp_state, DATA_BLOB *challenge)
    633 {
    634         NTSTATUS nt_status;
    635         struct auth_context *auth_context = gensec_ntlmssp_state->auth_context;
    636         const uint8_t *chal;
    637 
    638         if (challenge->length != 8) {
    639                 return NT_STATUS_INVALID_PARAMETER;
    640         }
    641 
    642         chal = challenge->data;
    643 
    644         nt_status = gensec_ntlmssp_state->auth_context->set_challenge(auth_context,
    645                                                                       chal,
    646                                                                       "NTLMSSP callback (NTLM2)");
    647 
    648         return nt_status;
    649 }
    650 
    651 /**
    652  * Check the password on an NTLMSSP login. 
    653  *
    654  * Return the session keys used on the connection.
    655  */
    656 
    657 static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    658                                             TALLOC_CTX *mem_ctx,
    659                                             DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
    660 {
    661         NTSTATUS nt_status;
    662         struct auth_usersupplied_info *user_info = talloc(mem_ctx, struct auth_usersupplied_info);
    663         if (!user_info) {
    664                 return NT_STATUS_NO_MEMORY;
    665         }
    666 
    667         user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
    668         user_info->flags = 0;
    669         user_info->mapped_state = false;
    670         user_info->client.account_name = gensec_ntlmssp_state->user;
    671         user_info->client.domain_name = gensec_ntlmssp_state->domain;
    672         user_info->workstation_name = gensec_ntlmssp_state->workstation;
    673         user_info->remote_host = gensec_get_peer_addr(gensec_ntlmssp_state->gensec_security);
    674 
    675         user_info->password_state = AUTH_PASSWORD_RESPONSE;
    676         user_info->password.response.lanman = gensec_ntlmssp_state->lm_resp;
    677         user_info->password.response.lanman.data = talloc_steal(user_info, gensec_ntlmssp_state->lm_resp.data);
    678         user_info->password.response.nt = gensec_ntlmssp_state->nt_resp;
    679         user_info->password.response.nt.data = talloc_steal(user_info, gensec_ntlmssp_state->nt_resp.data);
    680 
    681         nt_status = gensec_ntlmssp_state->auth_context->check_password(gensec_ntlmssp_state->auth_context,
    682                                                                        mem_ctx,
    683                                                                        user_info,
    684                                                                        &gensec_ntlmssp_state->server_info);
    685         talloc_free(user_info);
    686         NT_STATUS_NOT_OK_RETURN(nt_status);
    687 
    688         talloc_steal(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info);
    689 
    690         if (gensec_ntlmssp_state->server_info->user_session_key.length) {
    691                 DEBUG(10, ("Got NT session key of length %u\n",
    692                            (unsigned)gensec_ntlmssp_state->server_info->user_session_key.length));
    693                 if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->user_session_key.data)) {
    694                         return NT_STATUS_NO_MEMORY;
    695                 }
    696 
    697                 *user_session_key = gensec_ntlmssp_state->server_info->user_session_key;
    698         }
    699         if (gensec_ntlmssp_state->server_info->lm_session_key.length) {
    700                 DEBUG(10, ("Got LM session key of length %u\n",
    701                            (unsigned)gensec_ntlmssp_state->server_info->lm_session_key.length));
    702                 if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->lm_session_key.data)) {
    703                         return NT_STATUS_NO_MEMORY;
    704                 }
    705 
    706                 *lm_session_key = gensec_ntlmssp_state->server_info->lm_session_key;
    707         }
    708         return nt_status;
    709 }
    710 
    711 /**
    712  * Return the credentials of a logged on user, including session keys
    713  * etc.
    714  *
    715  * Only valid after a successful authentication
    716  *
    717  * May only be called once per authentication.
    718  *
    719  */
    720 
    721 NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
    722                                      struct auth_session_info **session_info)
    723 {
    724         NTSTATUS nt_status;
    725         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    726 
    727         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);
    728         NT_STATUS_NOT_OK_RETURN(nt_status);
    729 
    730         (*session_info)->session_key = data_blob_talloc(*session_info,
    731                                                         gensec_ntlmssp_state->session_key.data,
    732                                                         gensec_ntlmssp_state->session_key.length);
    733 
    734         return NT_STATUS_OK;
    735 }
    736 
    737 /**
    738  * Start NTLMSSP on the server side
    739  *
    740  */
    741 NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
    742 {
    743         NTSTATUS nt_status;
    744         struct gensec_ntlmssp_state *gensec_ntlmssp_state;
    745 
    746         nt_status = gensec_ntlmssp_start(gensec_security);
    747         NT_STATUS_NOT_OK_RETURN(nt_status);
    748 
    749         gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    750 
    751         gensec_ntlmssp_state->role = NTLMSSP_SERVER;
    752 
    753         gensec_ntlmssp_state->workstation = NULL;
    754         gensec_ntlmssp_state->server_name = lp_netbios_name(gensec_security->settings->lp_ctx);
    755 
    756         gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx);
    757 
    758         gensec_ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
    759 
    760         gensec_ntlmssp_state->allow_lm_key = (lp_lanman_auth(gensec_security->settings->lp_ctx)
    761                                           && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));
    762 
    763         gensec_ntlmssp_state->server_multiple_authentications = false;
    764        
    765         gensec_ntlmssp_state->neg_flags =
    766                 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;
    767 
    768         gensec_ntlmssp_state->lm_resp = data_blob(NULL, 0);
    769         gensec_ntlmssp_state->nt_resp = data_blob(NULL, 0);
    770         gensec_ntlmssp_state->encrypted_session_key = data_blob(NULL, 0);
    771 
    772         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
    773                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;               
    774         }
    775 
    776         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
    777                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;               
    778         }
    779 
    780         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
    781                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;         
    782         }
    783 
    784         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
    785                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;               
    786         }
    787 
    788         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
    789                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;             
    790         }
    791 
    792         if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
    793                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
    794         }
    795         if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
    796                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
    797         }
    798 
    799         gensec_ntlmssp_state->auth_context = gensec_security->auth_context;
    800 
    801         gensec_ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
    802         gensec_ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
    803         gensec_ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
    804         gensec_ntlmssp_state->check_password = auth_ntlmssp_check_password;
    805         gensec_ntlmssp_state->server_role = lp_server_role(gensec_security->settings->lp_ctx);
    806 
    807         return NT_STATUS_OK;
    808 }
    809 
Note: See TracChangeset for help on using the changeset viewer.