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