~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/libsmb/ntlmssp.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   Unix SMB/Netbios implementation.
3
 
   Version 3.0
4
 
   handle NLTMSSP, server side
5
 
 
6
 
   Copyright (C) Andrew Tridgell      2001
7
 
   Copyright (C) Andrew Bartlett 2001-2003
8
 
   Copyright (C) Andrew Bartlett 2005 (Updated from gensec).
9
 
 
10
 
   This program is free software; you can redistribute it and/or modify
11
 
   it under the terms of the GNU General Public License as published by
12
 
   the Free Software Foundation; either version 2 of the License, or
13
 
   (at your option) any later version.
14
 
   
15
 
   This program is distributed in the hope that it will be useful,
16
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
   GNU General Public License for more details.
19
 
   
20
 
   You should have received a copy of the GNU General Public License
21
 
   along with this program; if not, write to the Free Software
22
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
 
*/
24
 
 
25
 
#include "includes.h"
26
 
 
27
 
static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
28
 
                                       DATA_BLOB reply, DATA_BLOB *next_request);
29
 
static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
30
 
                                         const DATA_BLOB in, DATA_BLOB *out);
31
 
static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
32
 
                                         const DATA_BLOB reply, DATA_BLOB *next_request);
33
 
static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
34
 
                                    const DATA_BLOB request, DATA_BLOB *reply);
35
 
 
36
 
/**
37
 
 * Callbacks for NTLMSSP - for both client and server operating modes
38
 
 * 
39
 
 */
40
 
 
41
 
static const struct ntlmssp_callbacks {
42
 
        enum NTLMSSP_ROLE role;
43
 
        enum NTLM_MESSAGE_TYPE ntlmssp_command;
44
 
        NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, 
45
 
                       DATA_BLOB in, DATA_BLOB *out);
46
 
} ntlmssp_callbacks[] = {
47
 
        {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
48
 
        {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
49
 
        {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
50
 
        {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
51
 
        {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
52
 
        {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
53
 
};
54
 
 
55
 
 
56
 
/**
57
 
 * Print out the NTLMSSP flags for debugging 
58
 
 * @param neg_flags The flags from the packet
59
 
 */
60
 
 
61
 
void debug_ntlmssp_flags(uint32 neg_flags)
62
 
{
63
 
        DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
64
 
        
65
 
        if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) 
66
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_UNICODE\n"));
67
 
        if (neg_flags & NTLMSSP_NEGOTIATE_OEM) 
68
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM\n"));
69
 
        if (neg_flags & NTLMSSP_REQUEST_TARGET) 
70
 
                DEBUGADD(4, ("  NTLMSSP_REQUEST_TARGET\n"));
71
 
        if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) 
72
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SIGN\n"));
73
 
        if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) 
74
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SEAL\n"));
75
 
        if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM_STYLE)
76
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DATAGRAM_STYLE\n"));
77
 
        if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
78
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_LM_KEY\n"));
79
 
        if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) 
80
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NETWARE\n"));
81
 
        if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) 
82
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM\n"));
83
 
        if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) 
84
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"));
85
 
        if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) 
86
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n"));
87
 
        if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) 
88
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
89
 
        if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) 
90
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
91
 
        if (neg_flags & NTLMSSP_CHAL_ACCEPT_RESPONSE)
92
 
                DEBUGADD(4, ("  NTLMSSP_CHAL_ACCEPT_RESPONSE\n"));
93
 
        if (neg_flags & NTLMSSP_CHAL_NON_NT_SESSION_KEY)
94
 
                DEBUGADD(4, ("  NTLMSSP_CHAL_NON_NT_SESSION_KEY\n"));
95
 
        if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) 
96
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM2\n"));
97
 
        if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) 
98
 
                DEBUGADD(4, ("  NTLMSSP_CHAL_TARGET_INFO\n"));
99
 
        if (neg_flags & NTLMSSP_NEGOTIATE_128) 
100
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_128\n"));
101
 
        if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) 
102
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
103
 
        if (neg_flags & NTLMSSP_NEGOTIATE_56)
104
 
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_56\n"));
105
 
}
106
 
 
107
 
/**
108
 
 * Default challenge generation code.
109
 
 *
110
 
 */
111
 
   
112
 
static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
113
 
{
114
 
        static uchar chal[8];
115
 
        generate_random_buffer(chal, sizeof(chal));
116
 
 
117
 
        return chal;
118
 
}
119
 
 
120
 
/**
121
 
 * Default 'we can set the challenge to anything we like' implementation
122
 
 *
123
 
 */
124
 
   
125
 
static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
126
 
{
127
 
        return True;
128
 
}
129
 
 
130
 
/**
131
 
 * Default 'we can set the challenge to anything we like' implementation
132
 
 *
133
 
 * Does not actually do anything, as the value is always in the structure anyway.
134
 
 *
135
 
 */
136
 
   
137
 
static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
138
 
{
139
 
        SMB_ASSERT(challenge->length == 8);
140
 
        return NT_STATUS_OK;
141
 
}
142
 
 
143
 
/** 
144
 
 * Set a username on an NTLMSSP context - ensures it is talloc()ed 
145
 
 *
146
 
 */
147
 
 
148
 
NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) 
149
 
{
150
 
        ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user ? user : "" );
151
 
        if (!ntlmssp_state->user) {
152
 
                return NT_STATUS_NO_MEMORY;
153
 
        }
154
 
        return NT_STATUS_OK;
155
 
}
156
 
 
157
 
/** 
158
 
 * Set a password on an NTLMSSP context - ensures it is talloc()ed 
159
 
 *
160
 
 */
161
 
NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) 
162
 
{
163
 
        if (!password) {
164
 
                ntlmssp_state->password = NULL;
165
 
        } else {
166
 
                ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password);
167
 
                if (!ntlmssp_state->password) {
168
 
                        return NT_STATUS_NO_MEMORY;
169
 
                }
170
 
        }
171
 
        return NT_STATUS_OK;
172
 
}
173
 
 
174
 
/** 
175
 
 * Set a domain on an NTLMSSP context - ensures it is talloc()ed 
176
 
 *
177
 
 */
178
 
NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) 
179
 
{
180
 
        ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain ? domain : "" );
181
 
        if (!ntlmssp_state->domain) {
182
 
                return NT_STATUS_NO_MEMORY;
183
 
        }
184
 
        return NT_STATUS_OK;
185
 
}
186
 
 
187
 
/** 
188
 
 * Set a workstation on an NTLMSSP context - ensures it is talloc()ed 
189
 
 *
190
 
 */
191
 
NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) 
192
 
{
193
 
        ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation);
194
 
        if (!ntlmssp_state->workstation) {
195
 
                return NT_STATUS_NO_MEMORY;
196
 
        }
197
 
        return NT_STATUS_OK;
198
 
}
199
 
 
200
 
/**
201
 
 *  Store a DATA_BLOB containing an NTLMSSP response, for use later.
202
 
 *  This copies the data blob
203
 
 */
204
 
 
205
 
NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
206
 
                                DATA_BLOB response) 
207
 
{
208
 
        ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx, 
209
 
                                                          response.data, response.length);
210
 
        return NT_STATUS_OK;
211
 
}
212
 
 
213
 
/**
214
 
 * Next state function for the NTLMSSP state machine
215
 
 * 
216
 
 * @param ntlmssp_state NTLMSSP State
217
 
 * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
218
 
 * @param out The reply, as an allocated DATA_BLOB, caller to free.
219
 
 * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. 
220
 
 */
221
 
 
222
 
NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, 
223
 
                        const DATA_BLOB in, DATA_BLOB *out) 
224
 
{
225
 
        DATA_BLOB input;
226
 
        uint32 ntlmssp_command;
227
 
        int i;
228
 
 
229
 
        if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
230
 
                /* Called update after negotiations finished. */
231
 
                DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n"));
232
 
                return NT_STATUS_INVALID_PARAMETER;
233
 
        }
234
 
 
235
 
        *out = data_blob(NULL, 0);
236
 
 
237
 
        if (!in.length && ntlmssp_state->stored_response.length) {
238
 
                input = ntlmssp_state->stored_response;
239
 
                
240
 
                /* we only want to read the stored response once - overwrite it */
241
 
                ntlmssp_state->stored_response = data_blob(NULL, 0);
242
 
        } else {
243
 
                input = in;
244
 
        }
245
 
 
246
 
        if (!input.length) {
247
 
                switch (ntlmssp_state->role) {
248
 
                case NTLMSSP_CLIENT:
249
 
                        ntlmssp_command = NTLMSSP_INITIAL;
250
 
                        break;
251
 
                case NTLMSSP_SERVER:
252
 
                        /* 'datagram' mode - no neg packet */
253
 
                        ntlmssp_command = NTLMSSP_NEGOTIATE;
254
 
                        break;
255
 
                }
256
 
        } else {
257
 
                if (!msrpc_parse(&input, "Cd",
258
 
                                 "NTLMSSP",
259
 
                                 &ntlmssp_command)) {
260
 
                        DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
261
 
                        dump_data(2, (const char *)input.data, input.length);
262
 
                        return NT_STATUS_INVALID_PARAMETER;
263
 
                }
264
 
        }
265
 
 
266
 
        if (ntlmssp_command != ntlmssp_state->expected_state) {
267
 
                DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
268
 
                return NT_STATUS_INVALID_PARAMETER;
269
 
        }
270
 
 
271
 
        for (i=0; ntlmssp_callbacks[i].fn; i++) {
272
 
                if (ntlmssp_callbacks[i].role == ntlmssp_state->role 
273
 
                    && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {
274
 
                        return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out);
275
 
                }
276
 
        }
277
 
 
278
 
        DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", 
279
 
                  ntlmssp_state->role, ntlmssp_command)); 
280
 
 
281
 
        return NT_STATUS_INVALID_PARAMETER;
282
 
}
283
 
 
284
 
/**
285
 
 * End an NTLMSSP state machine
286
 
 * 
287
 
 * @param ntlmssp_state NTLMSSP State, free()ed by this function
288
 
 */
289
 
 
290
 
void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state)
291
 
{
292
 
        TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
293
 
 
294
 
        (*ntlmssp_state)->ref_count--;
295
 
 
296
 
        if ((*ntlmssp_state)->ref_count == 0) {
297
 
                data_blob_free(&(*ntlmssp_state)->chal);
298
 
                data_blob_free(&(*ntlmssp_state)->lm_resp);
299
 
                data_blob_free(&(*ntlmssp_state)->nt_resp);
300
 
 
301
 
                talloc_destroy(mem_ctx);
302
 
        }
303
 
 
304
 
        *ntlmssp_state = NULL;
305
 
        return;
306
 
}
307
 
 
308
 
/**
309
 
 * Determine correct target name flags for reply, given server role 
310
 
 * and negotiated flags
311
 
 * 
312
 
 * @param ntlmssp_state NTLMSSP State
313
 
 * @param neg_flags The flags from the packet
314
 
 * @param chal_flags The flags to be set in the reply packet
315
 
 * @return The 'target name' string.
316
 
 */
317
 
 
318
 
static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
319
 
                                       uint32 neg_flags, uint32 *chal_flags) 
320
 
{
321
 
        if (neg_flags & NTLMSSP_REQUEST_TARGET) {
322
 
                *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
323
 
                *chal_flags |= NTLMSSP_REQUEST_TARGET;
324
 
                if (ntlmssp_state->server_role == ROLE_STANDALONE) {
325
 
                        *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
326
 
                        return ntlmssp_state->get_global_myname();
327
 
                } else {
328
 
                        *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
329
 
                        return ntlmssp_state->get_domain();
330
 
                };
331
 
        } else {
332
 
                return "";
333
 
        }
334
 
}
335
 
 
336
 
static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
337
 
                                      uint32 neg_flags, BOOL allow_lm) {
338
 
        if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
339
 
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
340
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
341
 
                ntlmssp_state->unicode = True;
342
 
        } else {
343
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
344
 
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
345
 
                ntlmssp_state->unicode = False;
346
 
        }
347
 
 
348
 
        if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {
349
 
                /* other end forcing us to use LM */
350
 
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
351
 
                ntlmssp_state->use_ntlmv2 = False;
352
 
        } else {
353
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
354
 
        }
355
 
 
356
 
        if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) {
357
 
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
358
 
        }
359
 
 
360
 
        if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
361
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
362
 
        }
363
 
 
364
 
        if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
365
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
366
 
        }
367
 
 
368
 
        if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
369
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
370
 
        }
371
 
 
372
 
        if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
373
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
374
 
        }
375
 
 
376
 
        if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
377
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
378
 
        }
379
 
 
380
 
        if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
381
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
382
 
        }
383
 
 
384
 
        /* Woop Woop - unknown flag for Windows compatibility...
385
 
           What does this really do ? JRA. */
386
 
        if (!(neg_flags & NTLMSSP_UNKNOWN_02000000)) {
387
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_UNKNOWN_02000000;
388
 
        }
389
 
 
390
 
        if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
391
 
                ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
392
 
        }
393
 
}
394
 
 
395
 
/**
396
 
 Weaken NTLMSSP keys to cope with down-level clients and servers.
397
 
 
398
 
 We probably should have some parameters to control this, but as
399
 
 it only occours for LM_KEY connections, and this is controlled
400
 
 by the client lanman auth/lanman auth parameters, it isn't too bad.
401
 
*/
402
 
 
403
 
DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx)
404
 
{
405
 
        DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,
406
 
                                        ntlmssp_state->session_key.data,
407
 
                                        ntlmssp_state->session_key.length);
408
 
 
409
 
        /* Nothing to weaken.  We certainly don't want to 'extend' the length... */
410
 
        if (weakened_key.length < 16) {
411
 
                /* perhaps there was no key? */
412
 
                return weakened_key;
413
 
        }
414
 
 
415
 
        /* Key weakening not performed on the master key for NTLM2
416
 
           and does not occour for NTLM1.  Therefore we only need
417
 
           to do this for the LM_KEY.
418
 
        */
419
 
 
420
 
        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
421
 
                /* LM key doesn't support 128 bit crypto, so this is
422
 
                 * the best we can do.  If you negotiate 128 bit, but
423
 
                 * not 56, you end up with 40 bit... */
424
 
                if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
425
 
                        weakened_key.data[7] = 0xa0;
426
 
                } else { /* forty bits */
427
 
                        weakened_key.data[5] = 0xe5;
428
 
                        weakened_key.data[6] = 0x38;
429
 
                        weakened_key.data[7] = 0xb0;
430
 
                }
431
 
                weakened_key.length = 8;
432
 
        }
433
 
        return weakened_key;
434
 
}
435
 
 
436
 
/**
437
 
 * Next state function for the Negotiate packet
438
 
 * 
439
 
 * @param ntlmssp_state NTLMSSP State
440
 
 * @param request The request, as a DATA_BLOB
441
 
 * @param request The reply, as an allocated DATA_BLOB, caller to free.
442
 
 * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. 
443
 
 */
444
 
 
445
 
static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
446
 
                                         const DATA_BLOB request, DATA_BLOB *reply) 
447
 
{
448
 
        DATA_BLOB struct_blob;
449
 
        fstring dnsname, dnsdomname;
450
 
        uint32 neg_flags = 0;
451
 
        uint32 ntlmssp_command, chal_flags;
452
 
        const uint8 *cryptkey;
453
 
        const char *target_name;
454
 
 
455
 
        /* parse the NTLMSSP packet */
456
 
#if 0
457
 
        file_save("ntlmssp_negotiate.dat", request.data, request.length);
458
 
#endif
459
 
 
460
 
        if (request.length) {
461
 
                if ((request.length < 16) || !msrpc_parse(&request, "Cdd",
462
 
                                                        "NTLMSSP",
463
 
                                                        &ntlmssp_command,
464
 
                                                        &neg_flags)) {
465
 
                        DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
466
 
                                (unsigned int)request.length));
467
 
                        dump_data(2, (const char *)request.data, request.length);
468
 
                        return NT_STATUS_INVALID_PARAMETER;
469
 
                }
470
 
                debug_ntlmssp_flags(neg_flags);
471
 
        }
472
 
        
473
 
        ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
474
 
 
475
 
        /* Ask our caller what challenge they would like in the packet */
476
 
        cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
477
 
 
478
 
        /* Check if we may set the challenge */
479
 
        if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
480
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
481
 
        }
482
 
 
483
 
        /* The flags we send back are not just the negotiated flags,
484
 
         * they are also 'what is in this packet'.  Therfore, we
485
 
         * operate on 'chal_flags' from here on 
486
 
         */
487
 
 
488
 
        chal_flags = ntlmssp_state->neg_flags;
489
 
 
490
 
        /* get the right name to fill in as 'target' */
491
 
        target_name = ntlmssp_target_name(ntlmssp_state, 
492
 
                                          neg_flags, &chal_flags); 
493
 
        if (target_name == NULL) 
494
 
                return NT_STATUS_INVALID_PARAMETER;
495
 
 
496
 
        ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
497
 
        ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
498
 
        
499
 
 
500
 
        /* This should be a 'netbios domain -> DNS domain' mapping */
501
 
        dnsdomname[0] = '\0';
502
 
        get_mydnsdomname(dnsdomname);
503
 
        strlower_m(dnsdomname);
504
 
        
505
 
        dnsname[0] = '\0';
506
 
        get_mydnsfullname(dnsname);
507
 
        
508
 
        /* This creates the 'blob' of names that appears at the end of the packet */
509
 
        if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) 
510
 
        {
511
 
                msrpc_gen(&struct_blob, "aaaaa",
512
 
                          NTLMSSP_NAME_TYPE_DOMAIN, target_name,
513
 
                          NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
514
 
                          NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
515
 
                          NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
516
 
                          0, "");
517
 
        } else {
518
 
                struct_blob = data_blob(NULL, 0);
519
 
        }
520
 
 
521
 
        {
522
 
                /* Marshel the packet in the right format, be it unicode or ASCII */
523
 
                const char *gen_string;
524
 
                if (ntlmssp_state->unicode) {
525
 
                        gen_string = "CdUdbddB";
526
 
                } else {
527
 
                        gen_string = "CdAdbddB";
528
 
                }
529
 
                
530
 
                msrpc_gen(reply, gen_string,
531
 
                          "NTLMSSP", 
532
 
                          NTLMSSP_CHALLENGE,
533
 
                          target_name,
534
 
                          chal_flags,
535
 
                          cryptkey, 8,
536
 
                          0, 0,
537
 
                          struct_blob.data, struct_blob.length);
538
 
        }
539
 
                
540
 
        data_blob_free(&struct_blob);
541
 
 
542
 
        ntlmssp_state->expected_state = NTLMSSP_AUTH;
543
 
 
544
 
        return NT_STATUS_MORE_PROCESSING_REQUIRED;
545
 
}
546
 
 
547
 
/**
548
 
 * Next state function for the Authenticate packet
549
 
 * 
550
 
 * @param ntlmssp_state NTLMSSP State
551
 
 * @param request The request, as a DATA_BLOB
552
 
 * @param request The reply, as an allocated DATA_BLOB, caller to free.
553
 
 * @return Errors or NT_STATUS_OK. 
554
 
 */
555
 
 
556
 
static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
557
 
                                    const DATA_BLOB request, DATA_BLOB *reply) 
558
 
{
559
 
        DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
560
 
        DATA_BLOB user_session_key = data_blob(NULL, 0);
561
 
        DATA_BLOB lm_session_key = data_blob(NULL, 0);
562
 
        DATA_BLOB session_key = data_blob(NULL, 0);
563
 
        uint32 ntlmssp_command, auth_flags;
564
 
        NTSTATUS nt_status = NT_STATUS_OK;
565
 
 
566
 
        /* used by NTLM2 */
567
 
        BOOL doing_ntlm2 = False;
568
 
 
569
 
        uchar session_nonce[16];
570
 
        uchar session_nonce_hash[16];
571
 
 
572
 
        const char *parse_string;
573
 
        char *domain = NULL;
574
 
        char *user = NULL;
575
 
        char *workstation = NULL;
576
 
 
577
 
        /* parse the NTLMSSP packet */
578
 
        *reply = data_blob(NULL, 0);
579
 
 
580
 
#if 0
581
 
        file_save("ntlmssp_auth.dat", request.data, request.length);
582
 
#endif
583
 
 
584
 
        if (ntlmssp_state->unicode) {
585
 
                parse_string = "CdBBUUUBd";
586
 
        } else {
587
 
                parse_string = "CdBBAAABd";
588
 
        }
589
 
 
590
 
        data_blob_free(&ntlmssp_state->lm_resp);
591
 
        data_blob_free(&ntlmssp_state->nt_resp);
592
 
 
593
 
        ntlmssp_state->user = NULL;
594
 
        ntlmssp_state->domain = NULL;
595
 
        ntlmssp_state->workstation = NULL;
596
 
 
597
 
        /* now the NTLMSSP encoded auth hashes */
598
 
        if (!msrpc_parse(&request, parse_string,
599
 
                         "NTLMSSP", 
600
 
                         &ntlmssp_command, 
601
 
                         &ntlmssp_state->lm_resp,
602
 
                         &ntlmssp_state->nt_resp,
603
 
                         &domain, 
604
 
                         &user, 
605
 
                         &workstation,
606
 
                         &encrypted_session_key,
607
 
                         &auth_flags)) {
608
 
                SAFE_FREE(domain);
609
 
                SAFE_FREE(user);
610
 
                SAFE_FREE(workstation);
611
 
                data_blob_free(&encrypted_session_key);
612
 
                auth_flags = 0;
613
 
                
614
 
                /* Try again with a shorter string (Win9X truncates this packet) */
615
 
                if (ntlmssp_state->unicode) {
616
 
                        parse_string = "CdBBUUU";
617
 
                } else {
618
 
                        parse_string = "CdBBAAA";
619
 
                }
620
 
 
621
 
                /* now the NTLMSSP encoded auth hashes */
622
 
                if (!msrpc_parse(&request, parse_string,
623
 
                                 "NTLMSSP", 
624
 
                                 &ntlmssp_command, 
625
 
                                 &ntlmssp_state->lm_resp,
626
 
                                 &ntlmssp_state->nt_resp,
627
 
                                 &domain, 
628
 
                                 &user, 
629
 
                                 &workstation)) {
630
 
                        DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
631
 
                        dump_data(2, (const char *)request.data, request.length);
632
 
                        SAFE_FREE(domain);
633
 
                        SAFE_FREE(user);
634
 
                        SAFE_FREE(workstation);
635
 
 
636
 
                        return NT_STATUS_INVALID_PARAMETER;
637
 
                }
638
 
        }
639
 
 
640
 
        if (auth_flags)
641
 
                ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth());
642
 
 
643
 
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
644
 
                SAFE_FREE(domain);
645
 
                SAFE_FREE(user);
646
 
                SAFE_FREE(workstation);
647
 
                data_blob_free(&encrypted_session_key);
648
 
                return nt_status;
649
 
        }
650
 
 
651
 
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
652
 
                SAFE_FREE(domain);
653
 
                SAFE_FREE(user);
654
 
                SAFE_FREE(workstation);
655
 
                data_blob_free(&encrypted_session_key);
656
 
                return nt_status;
657
 
        }
658
 
 
659
 
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
660
 
                SAFE_FREE(domain);
661
 
                SAFE_FREE(user);
662
 
                SAFE_FREE(workstation);
663
 
                data_blob_free(&encrypted_session_key);
664
 
                return nt_status;
665
 
        }
666
 
 
667
 
        SAFE_FREE(domain);
668
 
        SAFE_FREE(user);
669
 
        SAFE_FREE(workstation);
670
 
 
671
 
        DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
672
 
                 ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
673
 
 
674
 
#if 0
675
 
        file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
676
 
        file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
677
 
#endif
678
 
 
679
 
        /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a 
680
 
           client challenge 
681
 
        
682
 
           However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
683
 
        */
684
 
        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
685
 
                if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
686
 
                        struct MD5Context md5_session_nonce_ctx;
687
 
                        SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
688
 
                        
689
 
                        doing_ntlm2 = True;
690
 
 
691
 
                        memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
692
 
                        memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
693
 
                        
694
 
                        MD5Init(&md5_session_nonce_ctx);
695
 
                        MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
696
 
                        MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
697
 
                        
698
 
                        ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8);
699
 
 
700
 
                        /* LM response is no longer useful */
701
 
                        data_blob_free(&ntlmssp_state->lm_resp);
702
 
 
703
 
                        /* We changed the effective challenge - set it */
704
 
                        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
705
 
                                data_blob_free(&encrypted_session_key);
706
 
                                return nt_status;
707
 
                        }
708
 
 
709
 
                        /* LM Key is incompatible. */
710
 
                        ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
711
 
                }
712
 
        }
713
 
 
714
 
        /*
715
 
         * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
716
 
         * is required (by "ntlm auth = no" and "lm auth = no" being set in the
717
 
         * smb.conf file) and no NTLMv2 response was sent then the password check
718
 
         * will fail here. JRA.
719
 
         */
720
 
 
721
 
        /* Finally, actually ask if the password is OK */
722
 
 
723
 
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, 
724
 
                                                                       &user_session_key, &lm_session_key))) {
725
 
                data_blob_free(&encrypted_session_key);
726
 
                return nt_status;
727
 
        }
728
 
 
729
 
        dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
730
 
        dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
731
 
 
732
 
        /* Handle the different session key derivation for NTLM2 */
733
 
        if (doing_ntlm2) {
734
 
                if (user_session_key.data && user_session_key.length == 16) {
735
 
                        session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
736
 
                        hmac_md5(user_session_key.data, session_nonce, 
737
 
                                 sizeof(session_nonce), session_key.data);
738
 
                        DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
739
 
                        dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
740
 
                        
741
 
                } else {
742
 
                        DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
743
 
                        session_key = data_blob(NULL, 0);
744
 
                }
745
 
        } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
746
 
                if (lm_session_key.data && lm_session_key.length >= 8) {
747
 
                        if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
748
 
                                session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
749
 
                                SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, 
750
 
                                                          session_key.data);
751
 
                                DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
752
 
                                dump_data_pw("LM session key:\n", session_key.data, session_key.length);
753
 
                        } else {
754
 
                                /* use the key unmodified - it's
755
 
                                 * probably a NULL key from the guest
756
 
                                 * login */
757
 
                                session_key = lm_session_key;
758
 
                        }
759
 
                } else {
760
 
                        DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
761
 
                        session_key = data_blob(NULL, 0);
762
 
                }
763
 
        } else if (user_session_key.data) {
764
 
                session_key = user_session_key;
765
 
                DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
766
 
                dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
767
 
        } else if (lm_session_key.data) {
768
 
                session_key = lm_session_key;
769
 
                DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
770
 
                dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
771
 
        } else {
772
 
                DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
773
 
                session_key = data_blob(NULL, 0);
774
 
        }
775
 
 
776
 
        /* With KEY_EXCH, the client supplies the proposed session key, 
777
 
           but encrypts it with the long-term key */
778
 
        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
779
 
                if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
780
 
                        data_blob_free(&encrypted_session_key);
781
 
                        DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", 
782
 
                                  (unsigned int)encrypted_session_key.length));
783
 
                        return NT_STATUS_INVALID_PARAMETER;
784
 
                } else if (!session_key.data || session_key.length != 16) {
785
 
                        DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", 
786
 
                                  (unsigned int)session_key.length));
787
 
                        ntlmssp_state->session_key = session_key;
788
 
                } else {
789
 
                        dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
790
 
                        SamOEMhash(encrypted_session_key.data, 
791
 
                                   session_key.data, 
792
 
                                   encrypted_session_key.length);
793
 
                        ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, 
794
 
                                                                      encrypted_session_key.data, 
795
 
                                                                      encrypted_session_key.length);
796
 
                        dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, 
797
 
                                     encrypted_session_key.length);
798
 
                }
799
 
        } else {
800
 
                ntlmssp_state->session_key = session_key;
801
 
        }
802
 
 
803
 
        if (!NT_STATUS_IS_OK(nt_status)) {
804
 
                ntlmssp_state->session_key = data_blob(NULL, 0);
805
 
        } else if (ntlmssp_state->session_key.length) {
806
 
                nt_status = ntlmssp_sign_init(ntlmssp_state);
807
 
        }
808
 
 
809
 
        data_blob_free(&encrypted_session_key);
810
 
        
811
 
        /* Only one authentication allowed per server state. */
812
 
        ntlmssp_state->expected_state = NTLMSSP_DONE;
813
 
 
814
 
        return nt_status;
815
 
}
816
 
 
817
 
/**
818
 
 * Create an NTLMSSP state machine
819
 
 * 
820
 
 * @param ntlmssp_state NTLMSSP State, allocated by this function
821
 
 */
822
 
 
823
 
NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
824
 
{
825
 
        TALLOC_CTX *mem_ctx;
826
 
 
827
 
        mem_ctx = talloc_init("NTLMSSP context");
828
 
        
829
 
        *ntlmssp_state = TALLOC_ZERO_P(mem_ctx, NTLMSSP_STATE);
830
 
        if (!*ntlmssp_state) {
831
 
                DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
832
 
                talloc_destroy(mem_ctx);
833
 
                return NT_STATUS_NO_MEMORY;
834
 
        }
835
 
 
836
 
        (*ntlmssp_state)->role = NTLMSSP_SERVER;
837
 
 
838
 
        (*ntlmssp_state)->mem_ctx = mem_ctx;
839
 
        (*ntlmssp_state)->get_challenge = get_challenge;
840
 
        (*ntlmssp_state)->set_challenge = set_challenge;
841
 
        (*ntlmssp_state)->may_set_challenge = may_set_challenge;
842
 
 
843
 
        (*ntlmssp_state)->get_global_myname = global_myname;
844
 
        (*ntlmssp_state)->get_domain = lp_workgroup;
845
 
        (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
846
 
 
847
 
        (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
848
 
 
849
 
        (*ntlmssp_state)->ref_count = 1;
850
 
 
851
 
        (*ntlmssp_state)->neg_flags = 
852
 
                NTLMSSP_NEGOTIATE_128 |
853
 
                NTLMSSP_NEGOTIATE_56 |
854
 
                NTLMSSP_UNKNOWN_02000000 |
855
 
                NTLMSSP_NEGOTIATE_NTLM |
856
 
                NTLMSSP_NEGOTIATE_NTLM2 |
857
 
                NTLMSSP_NEGOTIATE_KEY_EXCH |
858
 
                NTLMSSP_NEGOTIATE_SIGN |
859
 
                NTLMSSP_NEGOTIATE_SEAL;
860
 
 
861
 
        return NT_STATUS_OK;
862
 
}
863
 
 
864
 
/*********************************************************************
865
 
 Client side NTLMSSP
866
 
*********************************************************************/
867
 
 
868
 
/**
869
 
 * Next state function for the Initial packet
870
 
 * 
871
 
 * @param ntlmssp_state NTLMSSP State
872
 
 * @param request The request, as a DATA_BLOB.  reply.data must be NULL
873
 
 * @param request The reply, as an allocated DATA_BLOB, caller to free.
874
 
 * @return Errors or NT_STATUS_OK. 
875
 
 */
876
 
 
877
 
static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
878
 
                                  DATA_BLOB reply, DATA_BLOB *next_request) 
879
 
{
880
 
        if (ntlmssp_state->unicode) {
881
 
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
882
 
        } else {
883
 
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
884
 
        }
885
 
        
886
 
        if (ntlmssp_state->use_ntlmv2) {
887
 
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
888
 
        }
889
 
 
890
 
        /* generate the ntlmssp negotiate packet */
891
 
        msrpc_gen(next_request, "CddAA",
892
 
                  "NTLMSSP",
893
 
                  NTLMSSP_NEGOTIATE,
894
 
                  ntlmssp_state->neg_flags,
895
 
                  ntlmssp_state->get_domain(), 
896
 
                  ntlmssp_state->get_global_myname());
897
 
 
898
 
        ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
899
 
 
900
 
        return NT_STATUS_MORE_PROCESSING_REQUIRED;
901
 
}
902
 
 
903
 
/**
904
 
 * Next state function for the Challenge Packet.  Generate an auth packet.
905
 
 * 
906
 
 * @param ntlmssp_state NTLMSSP State
907
 
 * @param request The request, as a DATA_BLOB.  reply.data must be NULL
908
 
 * @param request The reply, as an allocated DATA_BLOB, caller to free.
909
 
 * @return Errors or NT_STATUS_OK. 
910
 
 */
911
 
 
912
 
static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
913
 
                                         const DATA_BLOB reply, DATA_BLOB *next_request) 
914
 
{
915
 
        uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
916
 
        DATA_BLOB server_domain_blob;
917
 
        DATA_BLOB challenge_blob;
918
 
        DATA_BLOB struct_blob = data_blob(NULL, 0);
919
 
        char *server_domain;
920
 
        const char *chal_parse_string;
921
 
        const char *auth_gen_string;
922
 
        DATA_BLOB lm_response = data_blob(NULL, 0);
923
 
        DATA_BLOB nt_response = data_blob(NULL, 0);
924
 
        DATA_BLOB session_key = data_blob(NULL, 0);
925
 
        DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
926
 
        NTSTATUS nt_status = NT_STATUS_OK;
927
 
 
928
 
        if (!msrpc_parse(&reply, "CdBd",
929
 
                         "NTLMSSP",
930
 
                         &ntlmssp_command, 
931
 
                         &server_domain_blob,
932
 
                         &chal_flags)) {
933
 
                DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
934
 
                dump_data(2, (const char *)reply.data, reply.length);
935
 
 
936
 
                return NT_STATUS_INVALID_PARAMETER;
937
 
        }
938
 
        
939
 
        data_blob_free(&server_domain_blob);
940
 
 
941
 
        DEBUG(3, ("Got challenge flags:\n"));
942
 
        debug_ntlmssp_flags(chal_flags);
943
 
 
944
 
        ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
945
 
 
946
 
        if (ntlmssp_state->unicode) {
947
 
                if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
948
 
                        chal_parse_string = "CdUdbddB";
949
 
                } else {
950
 
                        chal_parse_string = "CdUdbdd";
951
 
                }
952
 
                auth_gen_string = "CdBBUUUBd";
953
 
        } else {
954
 
                if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
955
 
                        chal_parse_string = "CdAdbddB";
956
 
                } else {
957
 
                        chal_parse_string = "CdAdbdd";
958
 
                }
959
 
 
960
 
                auth_gen_string = "CdBBAAABd";
961
 
        }
962
 
 
963
 
        DEBUG(3, ("NTLMSSP: Set final flags:\n"));
964
 
        debug_ntlmssp_flags(ntlmssp_state->neg_flags);
965
 
 
966
 
        if (!msrpc_parse(&reply, chal_parse_string,
967
 
                         "NTLMSSP",
968
 
                         &ntlmssp_command, 
969
 
                         &server_domain,
970
 
                         &chal_flags,
971
 
                         &challenge_blob, 8,
972
 
                         &unkn1, &unkn2,
973
 
                         &struct_blob)) {
974
 
                DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
975
 
                dump_data(2, (const char *)reply.data, reply.length);
976
 
                return NT_STATUS_INVALID_PARAMETER;
977
 
        }
978
 
 
979
 
        ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx,
980
 
                                                     server_domain);
981
 
 
982
 
        SAFE_FREE(server_domain);
983
 
        if (challenge_blob.length != 8) {
984
 
                data_blob_free(&struct_blob);
985
 
                return NT_STATUS_INVALID_PARAMETER;
986
 
        }
987
 
 
988
 
        if (!ntlmssp_state->password) {
989
 
                static const uchar zeros[16];
990
 
                /* do nothing - blobs are zero length */
991
 
 
992
 
                /* session key is all zeros */
993
 
                session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);
994
 
                
995
 
                /* not doing NLTM2 without a password */
996
 
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
997
 
        } else if (ntlmssp_state->use_ntlmv2) {
998
 
 
999
 
                if (!struct_blob.length) {
1000
 
                        /* be lazy, match win2k - we can't do NTLMv2 without it */
1001
 
                        DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
1002
 
                        return NT_STATUS_INVALID_PARAMETER;
1003
 
                }
1004
 
 
1005
 
                /* TODO: if the remote server is standalone, then we should replace 'domain'
1006
 
                   with the server name as supplied above */
1007
 
                
1008
 
                if (!SMBNTLMv2encrypt(ntlmssp_state->user, 
1009
 
                                      ntlmssp_state->domain, 
1010
 
                                      ntlmssp_state->password, &challenge_blob, 
1011
 
                                      &struct_blob, 
1012
 
                                      &lm_response, &nt_response, &session_key)) {
1013
 
                        data_blob_free(&challenge_blob);
1014
 
                        data_blob_free(&struct_blob);
1015
 
                        return NT_STATUS_NO_MEMORY;
1016
 
                }
1017
 
        } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
1018
 
                struct MD5Context md5_session_nonce_ctx;
1019
 
                uchar nt_hash[16];
1020
 
                uchar session_nonce[16];
1021
 
                uchar session_nonce_hash[16];
1022
 
                uchar user_session_key[16];
1023
 
                E_md4hash(ntlmssp_state->password, nt_hash);
1024
 
                
1025
 
                lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
1026
 
                generate_random_buffer(lm_response.data, 8);
1027
 
                memset(lm_response.data+8, 0, 16);
1028
 
 
1029
 
                memcpy(session_nonce, challenge_blob.data, 8);
1030
 
                memcpy(&session_nonce[8], lm_response.data, 8);
1031
 
        
1032
 
                MD5Init(&md5_session_nonce_ctx);
1033
 
                MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
1034
 
                MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
1035
 
                MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
1036
 
 
1037
 
                DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
1038
 
                DEBUG(5, ("challenge is: \n"));
1039
 
                dump_data(5, (const char *)session_nonce_hash, 8);
1040
 
                
1041
 
                nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
1042
 
                SMBNTencrypt(ntlmssp_state->password,
1043
 
                             session_nonce_hash,
1044
 
                             nt_response.data);
1045
 
 
1046
 
                session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
1047
 
 
1048
 
                SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key);
1049
 
                hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
1050
 
                dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
1051
 
        } else {
1052
 
                uchar lm_hash[16];
1053
 
                uchar nt_hash[16];
1054
 
                E_deshash(ntlmssp_state->password, lm_hash);
1055
 
                E_md4hash(ntlmssp_state->password, nt_hash);
1056
 
                
1057
 
                /* lanman auth is insecure, it may be disabled */
1058
 
                if (lp_client_lanman_auth()) {
1059
 
                        lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
1060
 
                        SMBencrypt(ntlmssp_state->password,challenge_blob.data,
1061
 
                                   lm_response.data);
1062
 
                }
1063
 
                
1064
 
                nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
1065
 
                SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
1066
 
                             nt_response.data);
1067
 
                
1068
 
                session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
1069
 
                if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
1070
 
                    && lp_client_lanman_auth()) {
1071
 
                        SMBsesskeygen_lm_sess_key(lm_hash, lm_response.data,
1072
 
                                        session_key.data);
1073
 
                        dump_data_pw("LM session key\n", session_key.data, session_key.length);
1074
 
                } else {
1075
 
                        SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
1076
 
                        dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1077
 
                }
1078
 
        }
1079
 
        data_blob_free(&struct_blob);
1080
 
 
1081
 
        /* Key exchange encryptes a new client-generated session key with
1082
 
           the password-derived key */
1083
 
        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1084
 
                /* Make up a new session key */
1085
 
                uint8 client_session_key[16];
1086
 
                generate_random_buffer(client_session_key, sizeof(client_session_key));
1087
 
 
1088
 
                /* Encrypt the new session key with the old one */
1089
 
                encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
1090
 
                dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1091
 
                SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
1092
 
                dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1093
 
 
1094
 
                /* Mark the new session key as the 'real' session key */
1095
 
                data_blob_free(&session_key);
1096
 
                session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
1097
 
        }
1098
 
 
1099
 
        /* this generates the actual auth packet */
1100
 
        if (!msrpc_gen(next_request, auth_gen_string, 
1101
 
                       "NTLMSSP", 
1102
 
                       NTLMSSP_AUTH, 
1103
 
                       lm_response.data, lm_response.length,
1104
 
                       nt_response.data, nt_response.length,
1105
 
                       ntlmssp_state->domain, 
1106
 
                       ntlmssp_state->user, 
1107
 
                       ntlmssp_state->get_global_myname(), 
1108
 
                       encrypted_session_key.data, encrypted_session_key.length,
1109
 
                       ntlmssp_state->neg_flags)) {
1110
 
                
1111
 
                return NT_STATUS_NO_MEMORY;
1112
 
        }
1113
 
 
1114
 
        data_blob_free(&encrypted_session_key);
1115
 
 
1116
 
        data_blob_free(&ntlmssp_state->chal);
1117
 
 
1118
 
        ntlmssp_state->session_key = session_key;
1119
 
 
1120
 
        ntlmssp_state->chal = challenge_blob;
1121
 
        ntlmssp_state->lm_resp = lm_response;
1122
 
        ntlmssp_state->nt_resp = nt_response;
1123
 
 
1124
 
        ntlmssp_state->expected_state = NTLMSSP_DONE;
1125
 
 
1126
 
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
1127
 
                DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
1128
 
        }
1129
 
 
1130
 
        return nt_status;
1131
 
}
1132
 
 
1133
 
NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
1134
 
{
1135
 
        TALLOC_CTX *mem_ctx;
1136
 
 
1137
 
        mem_ctx = talloc_init("NTLMSSP Client context");
1138
 
        
1139
 
        *ntlmssp_state = TALLOC_ZERO_P(mem_ctx, NTLMSSP_STATE);
1140
 
        if (!*ntlmssp_state) {
1141
 
                DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
1142
 
                talloc_destroy(mem_ctx);
1143
 
                return NT_STATUS_NO_MEMORY;
1144
 
        }
1145
 
 
1146
 
        (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1147
 
 
1148
 
        (*ntlmssp_state)->mem_ctx = mem_ctx;
1149
 
 
1150
 
        (*ntlmssp_state)->get_global_myname = global_myname;
1151
 
        (*ntlmssp_state)->get_domain = lp_workgroup;
1152
 
 
1153
 
        (*ntlmssp_state)->unicode = True;
1154
 
 
1155
 
        (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1156
 
 
1157
 
        (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1158
 
 
1159
 
        (*ntlmssp_state)->ref_count = 1;
1160
 
 
1161
 
        (*ntlmssp_state)->neg_flags = 
1162
 
                NTLMSSP_NEGOTIATE_128 |
1163
 
                NTLMSSP_NEGOTIATE_NTLM |
1164
 
                NTLMSSP_NEGOTIATE_NTLM2 |
1165
 
                NTLMSSP_NEGOTIATE_KEY_EXCH |
1166
 
                /*
1167
 
                 * We need to set this to allow a later SetPassword
1168
 
                 * via the SAMR pipe to succeed. Strange.... We could
1169
 
                 * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
1170
 
                 * */
1171
 
                NTLMSSP_NEGOTIATE_SIGN |
1172
 
                NTLMSSP_REQUEST_TARGET;
1173
 
 
1174
 
        return NT_STATUS_OK;
1175
 
}