Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libsmb/ntlmssp.c

    r414 r740  
    55
    66   Copyright (C) Andrew Tridgell      2001
    7    Copyright (C) Andrew Bartlett 2001-2003
    8    Copyright (C) Andrew Bartlett 2005 (Updated from gensec).
     7   Copyright (C) Andrew Bartlett 2001-2010
     8   Copyright (C) Stefan Metzmacher 2005
    99
    1010   This program is free software; you can redistribute it and/or modify
     
    2323
    2424#include "includes.h"
     25#include "../libcli/auth/ntlmssp.h"
     26#include "../libcli/auth/ntlmssp_private.h"
    2527#include "../libcli/auth/libcli_auth.h"
    2628#include "../librpc/gen_ndr/ndr_ntlmssp.h"
    27 #include "libsmb/ntlmssp_ndr.h"
     29#include "../libcli/auth/ntlmssp_ndr.h"
     30#include "../lib/crypto/md5.h"
     31#include "../lib/crypto/arcfour.h"
     32#include "../lib/crypto/hmacmd5.h"
     33#include "../nsswitch/libwbclient/wbclient.h"
    2834
    2935static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
     36                                       TALLOC_CTX *out_mem_ctx, /* Unused at this time */
    3037                                       DATA_BLOB reply, DATA_BLOB *next_request);
    31 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
    32                                          const DATA_BLOB in, DATA_BLOB *out);
    3338static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
     39                                         TALLOC_CTX *out_mem_ctx, /* Unused at this time */
    3440                                         const DATA_BLOB reply, DATA_BLOB *next_request);
    35 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
    36                                     const DATA_BLOB request, DATA_BLOB *reply);
    37 
    3841/**
    3942 * Callbacks for NTLMSSP - for both client and server operating modes
     
    4245
    4346static const struct ntlmssp_callbacks {
    44         enum NTLMSSP_ROLE role;
    45         enum NTLM_MESSAGE_TYPE ntlmssp_command;
     47        enum ntlmssp_role role;
     48        enum ntlmssp_message_type ntlmssp_command;
    4649        NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state,
     50                       TALLOC_CTX *out_mem_ctx,
    4751                       DATA_BLOB in, DATA_BLOB *out);
    4852} ntlmssp_callbacks[] = {
     
    5761
    5862/**
    59  * Print out the NTLMSSP flags for debugging
    60  * @param neg_flags The flags from the packet
    61  */
    62 
    63 void debug_ntlmssp_flags(uint32 neg_flags)
    64 {
    65         DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
    66 
    67         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)
    68                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_UNICODE\n"));
    69         if (neg_flags & NTLMSSP_NEGOTIATE_OEM)
    70                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM\n"));
    71         if (neg_flags & NTLMSSP_REQUEST_TARGET)
    72                 DEBUGADD(4, ("  NTLMSSP_REQUEST_TARGET\n"));
    73         if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)
    74                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SIGN\n"));
    75         if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)
    76                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SEAL\n"));
    77         if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM)
    78                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DATAGRAM\n"));
    79         if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
    80                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_LM_KEY\n"));
    81         if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)
    82                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NETWARE\n"));
    83         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)
    84                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM\n"));
    85         if (neg_flags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED)
    86                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED\n"));
    87         if (neg_flags & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED)
    88                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED\n"));
    89         if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)
    90                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
    91         if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
    92                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
    93         if (neg_flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY)
    94                 DEBUGADD(4, ("  NTLMSSP_REQUEST_NON_NT_SESSION_KEY\n"));
    95         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
    96                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM2\n"));
    97         if (neg_flags & NTLMSSP_NEGOTIATE_TARGET_INFO)
    98                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_TARGET_INFO\n"));
    99         if (neg_flags & NTLMSSP_NEGOTIATE_VERSION)
    100                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_VERSION\n"));
    101         if (neg_flags & NTLMSSP_NEGOTIATE_128)
    102                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_128\n"));
    103         if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
    104                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
    105         if (neg_flags & NTLMSSP_NEGOTIATE_56)
    106                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_56\n"));
    107 }
    108 
    109 /**
    11063 * Default challenge generation code.
    11164 *
    11265 */
    11366
    114 static void get_challenge(const struct ntlmssp_state *ntlmssp_state,
    115                           uint8_t chal[8])
     67static NTSTATUS get_challenge(const struct ntlmssp_state *ntlmssp_state,
     68                              uint8_t chal[8])
    11669{
    11770        generate_random_buffer(chal, 8);
     71        return NT_STATUS_OK;
    11872}
    11973
     
    146100 */
    147101
    148 NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user)
     102NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user)
    149103{
    150104        ntlmssp_state->user = talloc_strdup(ntlmssp_state, user ? user : "" );
     
    159113 *
    160114 */
    161 NTSTATUS ntlmssp_set_hashes(NTLMSSP_STATE *ntlmssp_state,
    162                 const unsigned char lm_hash[16],
    163                 const unsigned char nt_hash[16])
    164 {
    165         ntlmssp_state->lm_hash = (unsigned char *)
     115NTSTATUS ntlmssp_set_hashes(struct ntlmssp_state *ntlmssp_state,
     116                            const uint8_t lm_hash[16],
     117                            const uint8_t nt_hash[16])
     118{
     119        ntlmssp_state->lm_hash = (uint8_t *)
    166120                TALLOC_MEMDUP(ntlmssp_state, lm_hash, 16);
    167         ntlmssp_state->nt_hash = (unsigned char *)
     121        ntlmssp_state->nt_hash = (uint8_t *)
    168122                TALLOC_MEMDUP(ntlmssp_state, nt_hash, 16);
    169123        if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) {
     
    179133 *
    180134 */
    181 NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password)
     135NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password)
    182136{
    183137        if (!password) {
     
    185139                ntlmssp_state->nt_hash = NULL;
    186140        } else {
    187                 unsigned char lm_hash[16];
    188                 unsigned char nt_hash[16];
     141                uint8_t lm_hash[16];
     142                uint8_t nt_hash[16];
    189143
    190144                E_deshash(password, lm_hash);
     
    199153 *
    200154 */
    201 NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain)
     155NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain)
    202156{
    203157        ntlmssp_state->domain = talloc_strdup(ntlmssp_state,
     
    210164
    211165/**
    212  * Set a workstation on an NTLMSSP context - ensures it is talloc()ed
    213  *
    214  */
    215 NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation)
    216 {
    217         ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
    218         if (!ntlmssp_state->workstation) {
    219                 return NT_STATUS_NO_MEMORY;
    220         }
    221         return NT_STATUS_OK;
    222 }
    223 
    224 /**
    225  *  Store a DATA_BLOB containing an NTLMSSP response, for use later.
    226  *  This copies the data blob
    227  */
    228 
    229 NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
    230                                 DATA_BLOB response)
    231 {
    232         ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,
    233                                                           response.data,
    234                                                           response.length);
    235         return NT_STATUS_OK;
    236 }
    237 
    238 /**
    239166 * Request features for the NTLMSSP negotiation
    240167 *
     
    242169 * @param feature_list List of space seperated features requested from NTLMSSP.
    243170 */
    244 void ntlmssp_want_feature_list(NTLMSSP_STATE *ntlmssp_state, char *feature_list)
     171void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list)
    245172{
    246173        /*
     
    269196 * @param feature Bit flag specifying the requested feature
    270197 */
    271 void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature)
     198void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature)
    272199{
    273200        /* As per JRA's comment above */
     
    295222 */
    296223
    297 NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state,
    298                         const DATA_BLOB in, DATA_BLOB *out)
    299 {
    300         DATA_BLOB input;
    301         uint32 ntlmssp_command;
     224NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
     225                        const DATA_BLOB input, DATA_BLOB *out)
     226{
     227        uint32_t ntlmssp_command;
    302228        int i;
    303229
     
    309235
    310236        *out = data_blob_null;
    311 
    312         if (!in.length && ntlmssp_state->stored_response.length) {
    313                 input = ntlmssp_state->stored_response;
    314 
    315                 /* we only want to read the stored response once - overwrite it */
    316                 ntlmssp_state->stored_response = data_blob_null;
    317         } else {
    318                 input = in;
    319         }
    320237
    321238        if (!input.length) {
     
    328245                        ntlmssp_command = NTLMSSP_NEGOTIATE;
    329246                        break;
     247                default:
     248                        DEBUG(1, ("Invalid role: %d\n", ntlmssp_state->role));
     249                        return NT_STATUS_INVALID_PARAMETER;
    330250                }
    331251        } else {
     
    347267                if (ntlmssp_callbacks[i].role == ntlmssp_state->role
    348268                    && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {
    349                         return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out);
     269                        return ntlmssp_callbacks[i].fn(ntlmssp_state, ntlmssp_state, input, out);
    350270                }
    351271        }
     
    358278
    359279/**
    360  * End an NTLMSSP state machine
    361  *
    362  * @param ntlmssp_state NTLMSSP State, free()ed by this function
    363  */
    364 
    365 void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state)
    366 {
    367         (*ntlmssp_state)->ref_count--;
    368 
    369         if ((*ntlmssp_state)->ref_count == 0) {
    370                 data_blob_free(&(*ntlmssp_state)->chal);
    371                 data_blob_free(&(*ntlmssp_state)->lm_resp);
    372                 data_blob_free(&(*ntlmssp_state)->nt_resp);
    373                 TALLOC_FREE(*ntlmssp_state);
    374         }
    375 
    376         *ntlmssp_state = NULL;
    377         return;
    378 }
    379 
    380 /**
    381  * Determine correct target name flags for reply, given server role
    382  * and negotiated flags
    383  *
    384  * @param ntlmssp_state NTLMSSP State
    385  * @param neg_flags The flags from the packet
    386  * @param chal_flags The flags to be set in the reply packet
    387  * @return The 'target name' string.
    388  */
    389 
    390 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
    391                                        uint32 neg_flags, uint32 *chal_flags)
    392 {
    393         if (neg_flags & NTLMSSP_REQUEST_TARGET) {
    394                 *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
    395                 *chal_flags |= NTLMSSP_REQUEST_TARGET;
    396                 if (ntlmssp_state->server_role == ROLE_STANDALONE) {
    397                         *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
    398                         return ntlmssp_state->get_global_myname();
    399                 } else {
    400                         *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
    401                         return ntlmssp_state->get_domain();
    402                 };
    403         } else {
    404                 return "";
    405         }
    406 }
    407 
    408 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
    409                                       uint32 neg_flags, bool allow_lm) {
    410         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
    411                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
    412                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
    413                 ntlmssp_state->unicode = True;
    414         } else {
    415                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
    416                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
    417                 ntlmssp_state->unicode = False;
    418         }
    419 
    420         if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {
    421                 /* other end forcing us to use LM */
    422                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
    423                 ntlmssp_state->use_ntlmv2 = False;
    424         } else {
    425                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    426         }
    427 
    428         if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
    429                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
    430         }
    431 
    432         if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
    433                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    434         }
    435 
    436         if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
    437                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
    438         }
    439 
    440         if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
    441                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
    442         }
    443 
    444         if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
    445                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
    446         }
    447 
    448         if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
    449                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
    450         }
    451 
    452         if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
    453                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
    454         }
    455 
    456         /* Woop Woop - unknown flag for Windows compatibility...
    457            What does this really do ? JRA. */
    458         if (!(neg_flags & NTLMSSP_NEGOTIATE_VERSION)) {
    459                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_VERSION;
    460         }
    461 
    462         if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
    463                 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
    464         }
    465 }
    466 
    467 /**
    468  Weaken NTLMSSP keys to cope with down-level clients and servers.
    469 
    470  We probably should have some parameters to control this, but as
    471  it only occours for LM_KEY connections, and this is controlled
    472  by the client lanman auth/lanman auth parameters, it isn't too bad.
    473 */
    474 
    475 DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx)
    476 {
    477         DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,
    478                                         ntlmssp_state->session_key.data,
    479                                         ntlmssp_state->session_key.length);
    480 
    481         /* Nothing to weaken.  We certainly don't want to 'extend' the length... */
    482         if (weakened_key.length < 16) {
    483                 /* perhaps there was no key? */
    484                 return weakened_key;
    485         }
    486 
    487         /* Key weakening not performed on the master key for NTLM2
    488            and does not occour for NTLM1.  Therefore we only need
    489            to do this for the LM_KEY.
    490         */
    491 
    492         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
    493                 /* LM key doesn't support 128 bit crypto, so this is
    494                  * the best we can do.  If you negotiate 128 bit, but
    495                  * not 56, you end up with 40 bit... */
    496                 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
    497                         weakened_key.data[7] = 0xa0;
    498                 } else { /* forty bits */
    499                         weakened_key.data[5] = 0xe5;
    500                         weakened_key.data[6] = 0x38;
    501                         weakened_key.data[7] = 0xb0;
    502                 }
    503                 weakened_key.length = 8;
    504         }
    505         return weakened_key;
    506 }
    507 
    508 /**
    509  * Next state function for the Negotiate packet
    510  *
    511  * @param ntlmssp_state NTLMSSP State
    512  * @param request The request, as a DATA_BLOB
    513  * @param request The reply, as an allocated DATA_BLOB, caller to free.
    514  * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent.
    515  */
    516 
    517 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
    518                                          const DATA_BLOB request, DATA_BLOB *reply)
    519 {
    520         DATA_BLOB struct_blob;
    521         const char *dnsname;
    522         char *dnsdomname = NULL;
    523         uint32 neg_flags = 0;
    524         uint32 ntlmssp_command, chal_flags;
    525         uint8_t cryptkey[8];
    526         const char *target_name;
    527         struct NEGOTIATE_MESSAGE negotiate;
    528         struct CHALLENGE_MESSAGE challenge;
    529 
    530         /* parse the NTLMSSP packet */
    531 #if 0
    532         file_save("ntlmssp_negotiate.dat", request.data, request.length);
    533 #endif
    534 
    535         if (request.length) {
    536                 if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd",
    537                                                           "NTLMSSP",
    538                                                           &ntlmssp_command,
    539                                                           &neg_flags)) {
    540                         DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
    541                                 (unsigned int)request.length));
    542                         dump_data(2, request.data, request.length);
    543                         return NT_STATUS_INVALID_PARAMETER;
    544                 }
    545                 debug_ntlmssp_flags(neg_flags);
    546 
    547                 if (DEBUGLEVEL >= 10) {
    548                         if (NT_STATUS_IS_OK(ntlmssp_pull_NEGOTIATE_MESSAGE(&request,
    549                                                        ntlmssp_state,
    550                                                        NULL,
    551                                                        &negotiate)))
    552                         {
    553                                 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, &negotiate);
    554                         }
    555                 }
    556         }
    557 
    558         ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
    559 
    560         /* Ask our caller what challenge they would like in the packet */
    561         ntlmssp_state->get_challenge(ntlmssp_state, cryptkey);
    562 
    563         /* Check if we may set the challenge */
    564         if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
    565                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    566         }
    567 
    568         /* The flags we send back are not just the negotiated flags,
    569          * they are also 'what is in this packet'.  Therfore, we
    570          * operate on 'chal_flags' from here on
    571          */
    572 
    573         chal_flags = ntlmssp_state->neg_flags;
    574 
    575         /* get the right name to fill in as 'target' */
    576         target_name = ntlmssp_target_name(ntlmssp_state,
    577                                           neg_flags, &chal_flags);
    578         if (target_name == NULL)
    579                 return NT_STATUS_INVALID_PARAMETER;
    580 
    581         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
    582         ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state,
    583                                                         cryptkey, 8);
    584 
    585         /* This should be a 'netbios domain -> DNS domain' mapping */
    586         dnsdomname = get_mydnsdomname(ntlmssp_state);
    587         if (!dnsdomname) {
    588                 dnsdomname = talloc_strdup(ntlmssp_state, "");
    589         }
    590         if (!dnsdomname) {
    591                 return NT_STATUS_NO_MEMORY;
    592         }
    593         strlower_m(dnsdomname);
    594 
    595         dnsname = get_mydnsfullname();
    596         if (!dnsname) {
    597                 dnsname = "";
    598         }
    599 
    600         /* This creates the 'blob' of names that appears at the end of the packet */
    601         if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO)
    602         {
    603                 msrpc_gen(ntlmssp_state, &struct_blob, "aaaaa",
    604                           MsvAvNbDomainName, target_name,
    605                           MsvAvNbComputerName, ntlmssp_state->get_global_myname(),
    606                           MsvAvDnsDomainName, dnsdomname,
    607                           MsvAvDnsComputerName, dnsname,
    608                           MsvAvEOL, "");
    609         } else {
    610                 struct_blob = data_blob_null;
    611         }
    612 
    613         {
    614                 /* Marshel the packet in the right format, be it unicode or ASCII */
    615                 const char *gen_string;
    616                 if (ntlmssp_state->unicode) {
    617                         gen_string = "CdUdbddB";
    618                 } else {
    619                         gen_string = "CdAdbddB";
    620                 }
    621 
    622                 msrpc_gen(ntlmssp_state, reply, gen_string,
    623                           "NTLMSSP",
    624                           NTLMSSP_CHALLENGE,
    625                           target_name,
    626                           chal_flags,
    627                           cryptkey, 8,
    628                           0, 0,
    629                           struct_blob.data, struct_blob.length);
    630 
    631                 if (DEBUGLEVEL >= 10) {
    632                         if (NT_STATUS_IS_OK(ntlmssp_pull_CHALLENGE_MESSAGE(reply,
    633                                                        ntlmssp_state,
    634                                                        NULL,
    635                                                        &challenge)))
    636                         {
    637                                 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE, &challenge);
    638                         }
    639                 }
    640         }
    641 
    642         data_blob_free(&struct_blob);
    643 
    644         ntlmssp_state->expected_state = NTLMSSP_AUTH;
    645 
    646         return NT_STATUS_MORE_PROCESSING_REQUIRED;
    647 }
    648 
    649 /**
    650  * Next state function for the Authenticate packet
    651  *
    652  * @param ntlmssp_state NTLMSSP State
    653  * @param request The request, as a DATA_BLOB
    654  * @param request The reply, as an allocated DATA_BLOB, caller to free.
    655  * @return Errors or NT_STATUS_OK.
    656  */
    657 
    658 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
    659                                     const DATA_BLOB request, DATA_BLOB *reply)
    660 {
    661         DATA_BLOB encrypted_session_key = data_blob_null;
    662         DATA_BLOB user_session_key = data_blob_null;
    663         DATA_BLOB lm_session_key = data_blob_null;
    664         DATA_BLOB session_key = data_blob_null;
    665         uint32 ntlmssp_command, auth_flags;
    666         NTSTATUS nt_status = NT_STATUS_OK;
    667         struct AUTHENTICATE_MESSAGE authenticate;
    668 
    669         /* used by NTLM2 */
    670         bool doing_ntlm2 = False;
    671 
    672         uchar session_nonce[16];
    673         uchar session_nonce_hash[16];
    674 
    675         const char *parse_string;
    676 
    677         /* parse the NTLMSSP packet */
    678         *reply = data_blob_null;
    679 
    680 #if 0
    681         file_save("ntlmssp_auth.dat", request.data, request.length);
    682 #endif
    683 
    684         if (ntlmssp_state->unicode) {
    685                 parse_string = "CdBBUUUBd";
    686         } else {
    687                 parse_string = "CdBBAAABd";
    688         }
    689 
    690         data_blob_free(&ntlmssp_state->lm_resp);
    691         data_blob_free(&ntlmssp_state->nt_resp);
    692 
    693         ntlmssp_state->user = NULL;
    694         ntlmssp_state->domain = NULL;
    695         ntlmssp_state->workstation = NULL;
    696 
    697         /* now the NTLMSSP encoded auth hashes */
    698         if (!msrpc_parse(ntlmssp_state, &request, parse_string,
    699                          "NTLMSSP",
    700                          &ntlmssp_command,
    701                          &ntlmssp_state->lm_resp,
    702                          &ntlmssp_state->nt_resp,
    703                          &ntlmssp_state->domain,
    704                          &ntlmssp_state->user,
    705                          &ntlmssp_state->workstation,
    706                          &encrypted_session_key,
    707                          &auth_flags)) {
    708                 auth_flags = 0;
    709 
    710                 /* Try again with a shorter string (Win9X truncates this packet) */
    711                 if (ntlmssp_state->unicode) {
    712                         parse_string = "CdBBUUU";
    713                 } else {
    714                         parse_string = "CdBBAAA";
    715                 }
    716 
    717                 /* now the NTLMSSP encoded auth hashes */
    718                 if (!msrpc_parse(ntlmssp_state, &request, parse_string,
    719                                  "NTLMSSP",
    720                                  &ntlmssp_command,
    721                                  &ntlmssp_state->lm_resp,
    722                                  &ntlmssp_state->nt_resp,
    723                                  &ntlmssp_state->domain,
    724                                  &ntlmssp_state->user,
    725                                  &ntlmssp_state->workstation)) {
    726                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
    727                         dump_data(2, request.data, request.length);
    728 
    729                         return NT_STATUS_INVALID_PARAMETER;
    730                 }
    731         }
    732 
    733         if (auth_flags)
    734                 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth());
    735 
    736         if (DEBUGLEVEL >= 10) {
    737                 if (NT_STATUS_IS_OK(ntlmssp_pull_AUTHENTICATE_MESSAGE(&request,
    738                                                   ntlmssp_state,
    739                                                   NULL,
    740                                                   &authenticate)))
    741                 {
    742                         NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE, &authenticate);
    743                 }
    744         }
    745 
    746         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
    747                  ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
    748 
    749 #if 0
    750         file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
    751         file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
    752 #endif
    753 
    754         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
    755            client challenge
    756 
    757            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
    758         */
    759         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    760                 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
    761                         struct MD5Context md5_session_nonce_ctx;
    762                         SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
    763 
    764                         doing_ntlm2 = True;
    765 
    766                         memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
    767                         memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
    768 
    769                         MD5Init(&md5_session_nonce_ctx);
    770                         MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
    771                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
    772 
    773                         ntlmssp_state->chal = data_blob_talloc(
    774                                 ntlmssp_state, session_nonce_hash, 8);
    775 
    776                         /* LM response is no longer useful */
    777                         data_blob_free(&ntlmssp_state->lm_resp);
    778 
    779                         /* We changed the effective challenge - set it */
    780                         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
    781                                 data_blob_free(&encrypted_session_key);
    782                                 return nt_status;
    783                         }
    784 
    785                         /* LM Key is incompatible. */
    786                         ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    787                 }
    788         }
    789 
    790         /*
    791          * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
    792          * is required (by "ntlm auth = no" and "lm auth = no" being set in the
    793          * smb.conf file) and no NTLMv2 response was sent then the password check
    794          * will fail here. JRA.
    795          */
    796 
    797         /* Finally, actually ask if the password is OK */
    798 
    799         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state,
    800                                                                        &user_session_key, &lm_session_key))) {
    801                 data_blob_free(&encrypted_session_key);
    802                 return nt_status;
    803         }
    804 
    805         dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
    806         dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
    807 
    808         /* Handle the different session key derivation for NTLM2 */
    809         if (doing_ntlm2) {
    810                 if (user_session_key.data && user_session_key.length == 16) {
    811                         session_key = data_blob_talloc(ntlmssp_state,
    812                                                        NULL, 16);
    813                         hmac_md5(user_session_key.data, session_nonce,
    814                                  sizeof(session_nonce), session_key.data);
    815                         DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
    816                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
    817 
    818                 } else {
    819                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
    820                         session_key = data_blob_null;
    821                 }
    822         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
    823                 if (lm_session_key.data && lm_session_key.length >= 8) {
    824                         if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
    825                                 session_key = data_blob_talloc(ntlmssp_state,
    826                                                                NULL, 16);
    827                                 if (session_key.data == NULL) {
    828                                         return NT_STATUS_NO_MEMORY;
    829                                 }
    830                                 SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data,
    831                                                           session_key.data);
    832                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
    833                         } else {
    834                                 uint8 zeros[24];
    835                                 ZERO_STRUCT(zeros);
    836                                 session_key = data_blob_talloc(
    837                                         ntlmssp_state, NULL, 16);
    838                                 if (session_key.data == NULL) {
    839                                         return NT_STATUS_NO_MEMORY;
    840                                 }
    841                                 SMBsesskeygen_lm_sess_key(
    842                                         lm_session_key.data, zeros,
    843                                         session_key.data);
    844                         }
    845                         dump_data_pw("LM session key:\n", session_key.data,
    846                                      session_key.length);
    847                 } else {
    848                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
    849                         session_key = data_blob_null;
    850                 }
    851         } else if (user_session_key.data) {
    852                 session_key = user_session_key;
    853                 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
    854                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
    855         } else if (lm_session_key.data) {
    856                 session_key = lm_session_key;
    857                 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
    858                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
    859         } else {
    860                 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
    861                 session_key = data_blob_null;
    862         }
    863 
    864         /* With KEY_EXCH, the client supplies the proposed session key,
    865            but encrypts it with the long-term key */
    866         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    867                 if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
    868                         data_blob_free(&encrypted_session_key);
    869                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
    870                                   (unsigned int)encrypted_session_key.length));
    871                         return NT_STATUS_INVALID_PARAMETER;
    872                 } else if (!session_key.data || session_key.length != 16) {
    873                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
    874                                   (unsigned int)session_key.length));
    875                         ntlmssp_state->session_key = session_key;
    876                 } else {
    877                         dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
    878                         arcfour_crypt_blob(encrypted_session_key.data,
    879                                            encrypted_session_key.length,
    880                                            &session_key);
    881                         ntlmssp_state->session_key = data_blob_talloc(
    882                                 ntlmssp_state, encrypted_session_key.data,
    883                                 encrypted_session_key.length);
    884                         dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data,
    885                                      encrypted_session_key.length);
    886                 }
    887         } else {
    888                 ntlmssp_state->session_key = session_key;
    889         }
    890 
    891         if (!NT_STATUS_IS_OK(nt_status)) {
    892                 ntlmssp_state->session_key = data_blob_null;
    893         } else if (ntlmssp_state->session_key.length) {
    894                 nt_status = ntlmssp_sign_init(ntlmssp_state);
    895         }
    896 
    897         data_blob_free(&encrypted_session_key);
    898 
    899         /* Only one authentication allowed per server state. */
    900         ntlmssp_state->expected_state = NTLMSSP_DONE;
    901 
    902         return nt_status;
    903 }
    904 
    905 /**
    906280 * Create an NTLMSSP state machine
    907281 *
     
    909283 */
    910284
    911 NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
    912 {
    913         *ntlmssp_state = TALLOC_ZERO_P(NULL, NTLMSSP_STATE);
    914         if (!*ntlmssp_state) {
    915                 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
    916                 talloc_destroy(*ntlmssp_state);
    917                 return NT_STATUS_NO_MEMORY;
    918         }
    919 
    920         (*ntlmssp_state)->role = NTLMSSP_SERVER;
    921 
    922         (*ntlmssp_state)->get_challenge = get_challenge;
    923         (*ntlmssp_state)->set_challenge = set_challenge;
    924         (*ntlmssp_state)->may_set_challenge = may_set_challenge;
    925 
    926         (*ntlmssp_state)->get_global_myname = global_myname;
    927         (*ntlmssp_state)->get_domain = lp_workgroup;
    928         (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
    929 
    930         (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
    931 
    932         (*ntlmssp_state)->ref_count = 1;
    933 
    934         (*ntlmssp_state)->neg_flags =
     285NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx,
     286                              bool is_standalone,
     287                              const char *netbios_name,
     288                              const char *netbios_domain,
     289                              const char *dns_name,
     290                              const char *dns_domain,
     291                              struct ntlmssp_state **_ntlmssp_state)
     292{
     293        struct ntlmssp_state *ntlmssp_state;
     294
     295        if (!netbios_name) {
     296                netbios_name = "";
     297        }
     298
     299        if (!netbios_domain) {
     300                netbios_domain = "";
     301        }
     302
     303        if (!dns_domain) {
     304                dns_domain = "";
     305        }
     306
     307        if (!dns_name) {
     308                dns_name = "";
     309        }
     310
     311        ntlmssp_state = talloc_zero(mem_ctx, struct ntlmssp_state);
     312        if (!ntlmssp_state) {
     313                return NT_STATUS_NO_MEMORY;
     314        }
     315
     316        ntlmssp_state->role = NTLMSSP_SERVER;
     317
     318        ntlmssp_state->get_challenge = get_challenge;
     319        ntlmssp_state->set_challenge = set_challenge;
     320        ntlmssp_state->may_set_challenge = may_set_challenge;
     321
     322        ntlmssp_state->server.is_standalone = is_standalone;
     323
     324        ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
     325
     326        ntlmssp_state->allow_lm_key = lp_lanman_auth();
     327
     328        ntlmssp_state->neg_flags =
    935329                NTLMSSP_NEGOTIATE_128 |
    936330                NTLMSSP_NEGOTIATE_56 |
     
    943337                NTLMSSP_NEGOTIATE_SEAL;
    944338
     339        ntlmssp_state->server.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
     340        if (!ntlmssp_state->server.netbios_name) {
     341                talloc_free(ntlmssp_state);
     342                return NT_STATUS_NO_MEMORY;
     343        }
     344        ntlmssp_state->server.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain);
     345        if (!ntlmssp_state->server.netbios_domain) {
     346                talloc_free(ntlmssp_state);
     347                return NT_STATUS_NO_MEMORY;
     348        }
     349        ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state, dns_name);
     350        if (!ntlmssp_state->server.dns_name) {
     351                talloc_free(ntlmssp_state);
     352                return NT_STATUS_NO_MEMORY;
     353        }
     354        ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, dns_domain);
     355        if (!ntlmssp_state->server.dns_domain) {
     356                talloc_free(ntlmssp_state);
     357                return NT_STATUS_NO_MEMORY;
     358        }
     359
     360        *_ntlmssp_state = ntlmssp_state;
    945361        return NT_STATUS_OK;
    946362}
     
    960376
    961377static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
     378                                  TALLOC_CTX *out_mem_ctx, /* Unused at this time */
    962379                                  DATA_BLOB reply, DATA_BLOB *next_request)
    963380{
    964         struct NEGOTIATE_MESSAGE negotiate;
     381        NTSTATUS status;
    965382
    966383        if (ntlmssp_state->unicode) {
     
    975392
    976393        /* generate the ntlmssp negotiate packet */
    977         msrpc_gen(ntlmssp_state, next_request, "CddAA",
     394        status = msrpc_gen(ntlmssp_state, next_request, "CddAA",
    978395                  "NTLMSSP",
    979396                  NTLMSSP_NEGOTIATE,
    980397                  ntlmssp_state->neg_flags,
    981                   ntlmssp_state->get_domain(),
    982                   ntlmssp_state->get_global_myname());
     398                  ntlmssp_state->client.netbios_domain,
     399                  ntlmssp_state->client.netbios_name);
     400        if (!NT_STATUS_IS_OK(status)) {
     401                DEBUG(0, ("ntlmssp_client_initial: failed to generate "
     402                        "ntlmssp negotiate packet\n"));
     403                return status;
     404        }
    983405
    984406        if (DEBUGLEVEL >= 10) {
    985                 if (NT_STATUS_IS_OK(ntlmssp_pull_NEGOTIATE_MESSAGE(next_request,
    986                                                ntlmssp_state,
    987                                                NULL,
    988                                                &negotiate)))
    989                 {
    990                         NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, &negotiate);
     407                struct NEGOTIATE_MESSAGE *negotiate = talloc(
     408                        talloc_tos(), struct NEGOTIATE_MESSAGE);
     409                if (negotiate != NULL) {
     410                        status = ntlmssp_pull_NEGOTIATE_MESSAGE(
     411                                next_request, negotiate, negotiate);
     412                        if (NT_STATUS_IS_OK(status)) {
     413                                NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
     414                                                negotiate);
     415                        }
     416                        TALLOC_FREE(negotiate);
    991417                }
    992418        }
     
    1007433
    1008434static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
     435                                         TALLOC_CTX *out_mem_ctx, /* Unused at this time */
    1009436                                         const DATA_BLOB reply, DATA_BLOB *next_request)
    1010437{
    1011         uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
     438        uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
    1012439        DATA_BLOB server_domain_blob;
    1013440        DATA_BLOB challenge_blob;
     
    1021448        DATA_BLOB encrypted_session_key = data_blob_null;
    1022449        NTSTATUS nt_status = NT_STATUS_OK;
    1023         struct CHALLENGE_MESSAGE challenge;
    1024         struct AUTHENTICATE_MESSAGE authenticate;
    1025450
    1026451        if (ntlmssp_state->use_ccache) {
     
    1046471
    1047472                wbc_status = wbcCredentialCache(&params, &info, &error);
    1048                 if (error != NULL) {
    1049                         wbcFreeMemory(error);
    1050                 }
     473                wbcFreeMemory(error);
    1051474                if (!WBC_ERROR_IS_OK(wbc_status)) {
    1052475                        goto noccache;
     
    1088511
    1089512        if (DEBUGLEVEL >= 10) {
    1090                 if (NT_STATUS_IS_OK(ntlmssp_pull_CHALLENGE_MESSAGE(&reply,
    1091                                                ntlmssp_state,
    1092                                                NULL,
    1093                                                &challenge)))
    1094                 {
    1095                         NDR_PRINT_DEBUG(CHALLENGE_MESSAGE, &challenge);
     513                struct CHALLENGE_MESSAGE *challenge = talloc(
     514                        talloc_tos(), struct CHALLENGE_MESSAGE);
     515                if (challenge != NULL) {
     516                        NTSTATUS status;
     517                        challenge->NegotiateFlags = chal_flags;
     518                        status = ntlmssp_pull_CHALLENGE_MESSAGE(
     519                                &reply, challenge, challenge);
     520                        if (NT_STATUS_IS_OK(status)) {
     521                                NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
     522                                                challenge);
     523                        }
     524                        TALLOC_FREE(challenge);
    1096525                }
    1097526        }
     
    1137566        }
    1138567
    1139         ntlmssp_state->server_domain = server_domain;
     568        if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
     569                ntlmssp_state->server.is_standalone = true;
     570        } else {
     571                ntlmssp_state->server.is_standalone = false;
     572        }
     573        /* TODO: parse struct_blob and fill in the rest */
     574        ntlmssp_state->server.netbios_name = "";
     575        ntlmssp_state->server.netbios_domain = server_domain;
     576        ntlmssp_state->server.dns_name = "";
     577        ntlmssp_state->server.dns_domain = "";
    1140578
    1141579        if (challenge_blob.length != 8) {
     
    1145583
    1146584        if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) {
    1147                 uchar zeros[16];
     585                static const uint8_t zeros[16] = {0, };
    1148586                /* do nothing - blobs are zero length */
    1149 
    1150                 ZERO_STRUCT(zeros);
    1151587
    1152588                /* session key is all zeros */
     
    1178614        } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    1179615                struct MD5Context md5_session_nonce_ctx;
    1180                 uchar session_nonce[16];
    1181                 uchar session_nonce_hash[16];
    1182                 uchar user_session_key[16];
     616                uint8_t session_nonce[16];
     617                uint8_t session_nonce_hash[16];
     618                uint8_t user_session_key[16];
    1183619
    1184620                lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
     
    1238674        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    1239675                /* Make up a new session key */
    1240                 uint8 client_session_key[16];
     676                uint8_t client_session_key[16];
    1241677                generate_random_buffer(client_session_key, sizeof(client_session_key));
    1242678
     
    1255691
    1256692        /* this generates the actual auth packet */
    1257         if (!msrpc_gen(ntlmssp_state, next_request, auth_gen_string,
     693        nt_status = msrpc_gen(ntlmssp_state, next_request, auth_gen_string,
    1258694                       "NTLMSSP",
    1259695                       NTLMSSP_AUTH,
     
    1262698                       ntlmssp_state->domain,
    1263699                       ntlmssp_state->user,
    1264                        ntlmssp_state->get_global_myname(),
     700                       ntlmssp_state->client.netbios_name,
    1265701                       encrypted_session_key.data, encrypted_session_key.length,
    1266                        ntlmssp_state->neg_flags)) {
    1267 
     702                       ntlmssp_state->neg_flags);
     703
     704        if (!NT_STATUS_IS_OK(nt_status)) {
    1268705                return NT_STATUS_NO_MEMORY;
    1269706        }
    1270707
    1271708        if (DEBUGLEVEL >= 10) {
    1272                 if (NT_STATUS_IS_OK(ntlmssp_pull_AUTHENTICATE_MESSAGE(next_request,
    1273                                                   ntlmssp_state,
    1274                                                   NULL,
    1275                                                   &authenticate)))
    1276                 {
    1277                         NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE, &authenticate);
     709                struct AUTHENTICATE_MESSAGE *authenticate = talloc(
     710                        talloc_tos(), struct AUTHENTICATE_MESSAGE);
     711                if (authenticate != NULL) {
     712                        NTSTATUS status;
     713                        authenticate->NegotiateFlags =
     714                                ntlmssp_state->neg_flags;
     715                        status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
     716                                next_request, authenticate, authenticate);
     717                        if (NT_STATUS_IS_OK(status)) {
     718                                NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
     719                                                authenticate);
     720                        }
     721                        TALLOC_FREE(authenticate);
    1278722                }
    1279723        }
     
    1300744}
    1301745
    1302 NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
    1303 {
    1304         *ntlmssp_state = TALLOC_ZERO_P(NULL, NTLMSSP_STATE);
    1305         if (!*ntlmssp_state) {
    1306                 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
    1307                 talloc_destroy(*ntlmssp_state);
    1308                 return NT_STATUS_NO_MEMORY;
    1309         }
    1310 
    1311         (*ntlmssp_state)->role = NTLMSSP_CLIENT;
    1312 
    1313         (*ntlmssp_state)->get_global_myname = global_myname;
    1314         (*ntlmssp_state)->get_domain = lp_workgroup;
    1315 
    1316         (*ntlmssp_state)->unicode = True;
    1317 
    1318         (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
    1319 
    1320         (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
    1321 
    1322         (*ntlmssp_state)->ref_count = 1;
    1323 
    1324         (*ntlmssp_state)->neg_flags =
     746NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx,
     747                              const char *netbios_name,
     748                              const char *netbios_domain,
     749                              bool use_ntlmv2,
     750                              struct ntlmssp_state **_ntlmssp_state)
     751{
     752        struct ntlmssp_state *ntlmssp_state;
     753
     754        if (!netbios_name) {
     755                netbios_name = "";
     756        }
     757
     758        if (!netbios_domain) {
     759                netbios_domain = "";
     760        }
     761
     762        ntlmssp_state = talloc_zero(mem_ctx, struct ntlmssp_state);
     763        if (!ntlmssp_state) {
     764                return NT_STATUS_NO_MEMORY;
     765        }
     766
     767        ntlmssp_state->role = NTLMSSP_CLIENT;
     768
     769        ntlmssp_state->unicode = True;
     770
     771        ntlmssp_state->use_ntlmv2 = use_ntlmv2;
     772
     773        ntlmssp_state->expected_state = NTLMSSP_INITIAL;
     774
     775        ntlmssp_state->neg_flags =
    1325776                NTLMSSP_NEGOTIATE_128 |
    1326777                NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
     
    1330781                NTLMSSP_REQUEST_TARGET;
    1331782
     783        ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
     784        if (!ntlmssp_state->client.netbios_name) {
     785                talloc_free(ntlmssp_state);
     786                return NT_STATUS_NO_MEMORY;
     787        }
     788        ntlmssp_state->client.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain);
     789        if (!ntlmssp_state->client.netbios_domain) {
     790                talloc_free(ntlmssp_state);
     791                return NT_STATUS_NO_MEMORY;
     792        }
     793
     794        *_ntlmssp_state = ntlmssp_state;
    1332795        return NT_STATUS_OK;
    1333796}
Note: See TracChangeset for help on using the changeset viewer.