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