~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/libsmb/ntlmssp.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

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