fix some warnings from the Sun compiler
[samba.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         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_mydomname(dnsdomname);
437         strlower_m(dnsdomname);
438         
439         dnsname[0] = '\0';
440         get_myfullname(dnsname);
441         strlower_m(dnsname);
442         
443         /* This creates the 'blob' of names that appears at the end of the packet */
444         if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) 
445         {
446                 const char *target_name_dns = "";
447                 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
448                         target_name_dns = dnsdomname;
449                 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
450                         target_name_dns = dnsname;
451                 }
452
453                 msrpc_gen(&struct_blob, "aaaaa",
454                           NTLMSSP_NAME_TYPE_DOMAIN, target_name,
455                           NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
456                           NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
457                           NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
458                           0, "");
459         } else {
460                 struct_blob = data_blob(NULL, 0);
461         }
462
463         {
464                 /* Marshel the packet in the right format, be it unicode or ASCII */
465                 const char *gen_string;
466                 if (ntlmssp_state->unicode) {
467                         gen_string = "CdUdbddB";
468                 } else {
469                         gen_string = "CdAdbddB";
470                 }
471                 
472                 msrpc_gen(reply, gen_string,
473                           "NTLMSSP", 
474                           NTLMSSP_CHALLENGE,
475                           target_name,
476                           chal_flags,
477                           cryptkey, 8,
478                           0, 0,
479                           struct_blob.data, struct_blob.length);
480         }
481                 
482         data_blob_free(&struct_blob);
483
484         ntlmssp_state->expected_state = NTLMSSP_AUTH;
485
486         return NT_STATUS_MORE_PROCESSING_REQUIRED;
487 }
488
489 /**
490  * Next state function for the Authenticate packet
491  * 
492  * @param ntlmssp_state NTLMSSP State
493  * @param request The request, as a DATA_BLOB
494  * @param request The reply, as an allocated DATA_BLOB, caller to free.
495  * @return Errors or NT_STATUS_OK. 
496  */
497
498 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
499                                     const DATA_BLOB request, DATA_BLOB *reply) 
500 {
501         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
502         DATA_BLOB nt_session_key = data_blob(NULL, 0);
503         DATA_BLOB lm_session_key = data_blob(NULL, 0);
504         DATA_BLOB session_key = data_blob(NULL, 0);
505         uint32 ntlmssp_command, auth_flags;
506         NTSTATUS nt_status;
507
508         /* used by NTLM2 */
509         BOOL doing_ntlm2 = False;
510
511         uchar session_nonce[16];
512         uchar session_nonce_hash[16];
513
514         const char *parse_string;
515         char *domain = NULL;
516         char *user = NULL;
517         char *workstation = NULL;
518
519         /* parse the NTLMSSP packet */
520         *reply = data_blob(NULL, 0);
521
522 #if 0
523         file_save("ntlmssp_auth.dat", request.data, request.length);
524 #endif
525
526         if (ntlmssp_state->unicode) {
527                 parse_string = "CdBBUUUBd";
528         } else {
529                 parse_string = "CdBBAAABd";
530         }
531
532         data_blob_free(&ntlmssp_state->lm_resp);
533         data_blob_free(&ntlmssp_state->nt_resp);
534
535         ntlmssp_state->user = NULL;
536         ntlmssp_state->domain = NULL;
537         ntlmssp_state->workstation = NULL;
538
539         /* now the NTLMSSP encoded auth hashes */
540         if (!msrpc_parse(&request, parse_string,
541                          "NTLMSSP", 
542                          &ntlmssp_command, 
543                          &ntlmssp_state->lm_resp,
544                          &ntlmssp_state->nt_resp,
545                          &domain, 
546                          &user, 
547                          &workstation,
548                          &encrypted_session_key,
549                          &auth_flags)) {
550                 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
551                 dump_data(2, (const char *)request.data, request.length);
552                 SAFE_FREE(domain);
553                 SAFE_FREE(user);
554                 SAFE_FREE(workstation);
555                 data_blob_free(&encrypted_session_key);
556                 auth_flags = 0;
557                 
558                 /* Try again with a shorter string (Win9X truncates this packet) */
559                 if (ntlmssp_state->unicode) {
560                         parse_string = "CdBBUUU";
561                 } else {
562                         parse_string = "CdBBAAA";
563                 }
564
565                 /* now the NTLMSSP encoded auth hashes */
566                 if (!msrpc_parse(&request, parse_string,
567                                  "NTLMSSP", 
568                                  &ntlmssp_command, 
569                                  &ntlmssp_state->lm_resp,
570                                  &ntlmssp_state->nt_resp,
571                                  &domain, 
572                                  &user, 
573                                  &workstation)) {
574                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
575                         dump_data(2, (const char *)request.data, request.length);
576                         SAFE_FREE(domain);
577                         SAFE_FREE(user);
578                         SAFE_FREE(workstation);
579
580                         return NT_STATUS_INVALID_PARAMETER;
581                 }
582         }
583
584         if (auth_flags)
585                 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth());
586
587         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
588                 SAFE_FREE(domain);
589                 SAFE_FREE(user);
590                 SAFE_FREE(workstation);
591                 data_blob_free(&encrypted_session_key);
592                 return nt_status;
593         }
594
595         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
596                 SAFE_FREE(domain);
597                 SAFE_FREE(user);
598                 SAFE_FREE(workstation);
599                 data_blob_free(&encrypted_session_key);
600                 return nt_status;
601         }
602
603         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
604                 SAFE_FREE(domain);
605                 SAFE_FREE(user);
606                 SAFE_FREE(workstation);
607                 data_blob_free(&encrypted_session_key);
608                 return nt_status;
609         }
610
611         SAFE_FREE(domain);
612         SAFE_FREE(user);
613         SAFE_FREE(workstation);
614
615         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
616                  ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
617
618 #if 0
619         file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
620         file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
621 #endif
622
623         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a 
624            client challenge 
625         
626            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
627         */
628         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
629                 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
630                         struct MD5Context md5_session_nonce_ctx;
631                         SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
632                         
633                         doing_ntlm2 = True;
634
635                         memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
636                         memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
637                         
638                         MD5Init(&md5_session_nonce_ctx);
639                         MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
640                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
641                         
642                         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8);
643
644                         /* LM response is no longer useful */
645                         data_blob_free(&ntlmssp_state->lm_resp);
646
647                         /* We changed the effective challenge - set it */
648                         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
649                                 data_blob_free(&encrypted_session_key);
650                                 return nt_status;
651                         }
652                 }
653         }
654
655         /*
656          * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
657          * is required (by "ntlm auth = no" and "lm auth = no" being set in the
658          * smb.conf file) and no NTLMv2 response was sent then the password check
659          * will fail here. JRA.
660          */
661
662         /* Finally, actually ask if the password is OK */
663
664         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, 
665                                                                        &nt_session_key, &lm_session_key))) {
666                 data_blob_free(&encrypted_session_key);
667                 return nt_status;
668         }
669
670         dump_data_pw("NT session key:\n", nt_session_key.data, nt_session_key.length);
671         dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
672
673         /* Handle the different session key derivation for NTLM2 */
674         if (doing_ntlm2) {
675                 if (nt_session_key.data && nt_session_key.length == 16) {
676                         session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
677                         hmac_md5(nt_session_key.data, session_nonce, 
678                                  sizeof(session_nonce), session_key.data);
679                         DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
680                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
681                         
682                 } else {
683                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
684                         session_key = data_blob(NULL, 0);
685                 }
686         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
687                 if (lm_session_key.data && lm_session_key.length >= 8) {
688                         if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
689                                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
690                                 SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, 
691                                                           session_key.data);
692                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
693                                 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
694                         } else {
695                                 /* use the key unmodified - it's
696                                  * probably a NULL key from the guest
697                                  * login */
698                                 session_key = lm_session_key;
699                         }
700                 } else {
701                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
702                         session_key = data_blob(NULL, 0);
703                 }
704         } else if (nt_session_key.data) {
705                 session_key = nt_session_key;
706                 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
707                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
708         } else if (lm_session_key.data) {
709                 session_key = lm_session_key;
710                 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
711                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
712         } else {
713                 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
714                 session_key = data_blob(NULL, 0);
715         }
716
717         /* With KEY_EXCH, the client supplies the proposed session key, 
718            but encrypts it with the long-term key */
719         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
720                 if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
721                         data_blob_free(&encrypted_session_key);
722                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", 
723                                   encrypted_session_key.length));
724                         return NT_STATUS_INVALID_PARAMETER;
725                 } else if (!session_key.data || session_key.length != 16) {
726                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", 
727                                   session_key.length));
728                         ntlmssp_state->session_key = session_key;
729                 } else {
730                         dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
731                         SamOEMhash(encrypted_session_key.data, 
732                                    session_key.data, 
733                                    encrypted_session_key.length);
734                         ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, 
735                                                                       encrypted_session_key.data, 
736                                                                       encrypted_session_key.length);
737                         dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, 
738                                      encrypted_session_key.length);
739                 }
740         } else {
741                 ntlmssp_state->session_key = session_key;
742         }
743
744         if (!NT_STATUS_IS_OK(nt_status)) {
745                 ntlmssp_state->session_key = data_blob(NULL, 0);
746         } else if (ntlmssp_state->session_key.length) {
747                 nt_status = ntlmssp_sign_init(ntlmssp_state);
748         }
749
750         data_blob_free(&encrypted_session_key);
751         
752         /* allow arbitarily many authentications */
753         ntlmssp_state->expected_state = NTLMSSP_AUTH;
754
755         return nt_status;
756 }
757
758 /**
759  * Create an NTLMSSP state machine
760  * 
761  * @param ntlmssp_state NTLMSSP State, allocated by this function
762  */
763
764 NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
765 {
766         TALLOC_CTX *mem_ctx;
767
768         mem_ctx = talloc_init("NTLMSSP context");
769         
770         *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
771         if (!*ntlmssp_state) {
772                 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
773                 talloc_destroy(mem_ctx);
774                 return NT_STATUS_NO_MEMORY;
775         }
776
777         (*ntlmssp_state)->role = NTLMSSP_SERVER;
778
779         (*ntlmssp_state)->mem_ctx = mem_ctx;
780         (*ntlmssp_state)->get_challenge = get_challenge;
781         (*ntlmssp_state)->set_challenge = set_challenge;
782         (*ntlmssp_state)->may_set_challenge = may_set_challenge;
783
784         (*ntlmssp_state)->get_global_myname = global_myname;
785         (*ntlmssp_state)->get_domain = lp_workgroup;
786         (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
787
788         (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
789
790         (*ntlmssp_state)->ref_count = 1;
791
792         (*ntlmssp_state)->neg_flags = 
793                 NTLMSSP_NEGOTIATE_128 |
794                 NTLMSSP_NEGOTIATE_NTLM |
795                 NTLMSSP_NEGOTIATE_NTLM2 |
796                 NTLMSSP_NEGOTIATE_KEY_EXCH |
797                 NTLMSSP_NEGOTIATE_SIGN;
798
799         return NT_STATUS_OK;
800 }
801
802 /*********************************************************************
803  Client side NTLMSSP
804 *********************************************************************/
805
806 /**
807  * Next state function for the Initial packet
808  * 
809  * @param ntlmssp_state NTLMSSP State
810  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
811  * @param request The reply, as an allocated DATA_BLOB, caller to free.
812  * @return Errors or NT_STATUS_OK. 
813  */
814
815 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
816                                   DATA_BLOB reply, DATA_BLOB *next_request) 
817 {
818         if (ntlmssp_state->unicode) {
819                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
820         } else {
821                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
822         }
823         
824         if (ntlmssp_state->use_ntlmv2) {
825                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
826         }
827
828         /* generate the ntlmssp negotiate packet */
829         msrpc_gen(next_request, "CddAA",
830                   "NTLMSSP",
831                   NTLMSSP_NEGOTIATE,
832                   ntlmssp_state->neg_flags,
833                   ntlmssp_state->get_domain(), 
834                   ntlmssp_state->get_global_myname());
835
836         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
837
838         return NT_STATUS_MORE_PROCESSING_REQUIRED;
839 }
840
841 /**
842  * Next state function for the Challenge Packet.  Generate an auth packet.
843  * 
844  * @param ntlmssp_state NTLMSSP State
845  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
846  * @param request The reply, as an allocated DATA_BLOB, caller to free.
847  * @return Errors or NT_STATUS_OK. 
848  */
849
850 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
851                                          const DATA_BLOB reply, DATA_BLOB *next_request) 
852 {
853         uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
854         DATA_BLOB server_domain_blob;
855         DATA_BLOB challenge_blob;
856         DATA_BLOB struct_blob = data_blob(NULL, 0);
857         char *server_domain;
858         const char *chal_parse_string;
859         const char *auth_gen_string;
860         DATA_BLOB lm_response = data_blob(NULL, 0);
861         DATA_BLOB nt_response = data_blob(NULL, 0);
862         DATA_BLOB session_key = data_blob(NULL, 0);
863         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
864         NTSTATUS nt_status;
865
866         if (!msrpc_parse(&reply, "CdBd",
867                          "NTLMSSP",
868                          &ntlmssp_command, 
869                          &server_domain_blob,
870                          &chal_flags)) {
871                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
872                 dump_data(2, (const char *)reply.data, reply.length);
873
874                 return NT_STATUS_INVALID_PARAMETER;
875         }
876         
877         data_blob_free(&server_domain_blob);
878
879         DEBUG(3, ("Got challenge flags:\n"));
880         debug_ntlmssp_flags(chal_flags);
881
882         ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
883
884         if (ntlmssp_state->unicode) {
885                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
886                         chal_parse_string = "CdUdbddB";
887                 } else {
888                         chal_parse_string = "CdUdbdd";
889                 }
890                 auth_gen_string = "CdBBUUUBd";
891         } else {
892                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
893                         chal_parse_string = "CdAdbddB";
894                 } else {
895                         chal_parse_string = "CdAdbdd";
896                 }
897
898                 auth_gen_string = "CdBBAAABd";
899         }
900
901         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
902         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
903
904         if (!msrpc_parse(&reply, chal_parse_string,
905                          "NTLMSSP",
906                          &ntlmssp_command, 
907                          &server_domain,
908                          &chal_flags,
909                          &challenge_blob, 8,
910                          &unkn1, &unkn2,
911                          &struct_blob)) {
912                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
913                 dump_data(2, (const char *)reply.data, reply.length);
914                 return NT_STATUS_INVALID_PARAMETER;
915         }
916
917         ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx,
918                                                      server_domain);
919
920         SAFE_FREE(server_domain);
921         if (challenge_blob.length != 8) {
922                 data_blob_free(&struct_blob);
923                 return NT_STATUS_INVALID_PARAMETER;
924         }
925
926         if (!ntlmssp_state->password) {
927                 static const uchar zeros[16];
928                 /* do nothing - blobs are zero length */
929
930                 /* session key is all zeros */
931                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);
932                 
933                 /* not doing NLTM2 without a password */
934                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
935         } else if (ntlmssp_state->use_ntlmv2) {
936
937                 if (!struct_blob.length) {
938                         /* be lazy, match win2k - we can't do NTLMv2 without it */
939                         DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
940                         return NT_STATUS_INVALID_PARAMETER;
941                 }
942
943                 /* TODO: if the remote server is standalone, then we should replace 'domain'
944                    with the server name as supplied above */
945                 
946                 if (!SMBNTLMv2encrypt(ntlmssp_state->user, 
947                                       ntlmssp_state->domain, 
948                                       ntlmssp_state->password, &challenge_blob, 
949                                       &struct_blob, 
950                                       &lm_response, &nt_response, &session_key)) {
951                         data_blob_free(&challenge_blob);
952                         data_blob_free(&struct_blob);
953                         return NT_STATUS_NO_MEMORY;
954                 }
955         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
956                 struct MD5Context md5_session_nonce_ctx;
957                 uchar nt_hash[16];
958                 uchar session_nonce[16];
959                 uchar session_nonce_hash[16];
960                 uchar nt_session_key[16];
961                 E_md4hash(ntlmssp_state->password, nt_hash);
962                 
963                 lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
964                 generate_random_buffer(lm_response.data, 8, False);
965                 memset(lm_response.data+8, 0, 16);
966
967                 memcpy(session_nonce, challenge_blob.data, 8);
968                 memcpy(&session_nonce[8], lm_response.data, 8);
969         
970                 MD5Init(&md5_session_nonce_ctx);
971                 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
972                 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
973                 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
974
975                 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
976                 DEBUG(5, ("challenge is: \n"));
977                 dump_data(5, (const char *)session_nonce_hash, 8);
978                 
979                 nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
980                 SMBNTencrypt(ntlmssp_state->password,
981                              session_nonce_hash,
982                              nt_response.data);
983
984                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
985
986                 SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key);
987                 hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data);
988                 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
989         } else {
990                 
991                 
992                 uchar lm_hash[16];
993                 uchar nt_hash[16];
994                 E_deshash(ntlmssp_state->password, lm_hash);
995                 E_md4hash(ntlmssp_state->password, nt_hash);
996                 
997                 /* lanman auth is insecure, it may be disabled */
998                 if (lp_client_lanman_auth()) {
999                         lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
1000                         SMBencrypt(ntlmssp_state->password,challenge_blob.data,
1001                                    lm_response.data);
1002                 }
1003                 
1004                 nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
1005                 SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
1006                              nt_response.data);
1007                 
1008                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
1009                 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
1010                     && lp_client_lanman_auth()) {
1011                         SMBsesskeygen_lmv1(lm_hash, lm_response.data, 
1012                                            session_key.data);
1013                         dump_data_pw("LM session key\n", session_key.data, session_key.length);
1014                 } else {
1015                         SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
1016                         dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1017                 }
1018         }
1019         data_blob_free(&struct_blob);
1020
1021         /* Key exchange encryptes a new client-generated session key with
1022            the password-derived key */
1023         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1024                 uint8 client_session_key[16];
1025                 
1026                 generate_random_buffer(client_session_key, sizeof(client_session_key), False);  
1027                 encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
1028                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1029
1030                 SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
1031                 data_blob_free(&session_key);
1032                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
1033                 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1034         }
1035
1036         /* this generates the actual auth packet */
1037         if (!msrpc_gen(next_request, auth_gen_string, 
1038                        "NTLMSSP", 
1039                        NTLMSSP_AUTH, 
1040                        lm_response.data, lm_response.length,
1041                        nt_response.data, nt_response.length,
1042                        ntlmssp_state->domain, 
1043                        ntlmssp_state->user, 
1044                        ntlmssp_state->get_global_myname(), 
1045                        encrypted_session_key.data, encrypted_session_key.length,
1046                        ntlmssp_state->neg_flags)) {
1047                 
1048                 return NT_STATUS_NO_MEMORY;
1049         }
1050
1051         data_blob_free(&encrypted_session_key);
1052
1053         data_blob_free(&ntlmssp_state->chal);
1054
1055         ntlmssp_state->chal = challenge_blob;
1056         ntlmssp_state->lm_resp = lm_response;
1057         ntlmssp_state->nt_resp = nt_response;
1058         ntlmssp_state->session_key = session_key;
1059
1060         ntlmssp_state->expected_state = NTLMSSP_UNKNOWN;
1061
1062         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
1063                 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
1064                 return nt_status;
1065         }
1066
1067         return NT_STATUS_MORE_PROCESSING_REQUIRED;
1068 }
1069
1070 NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
1071 {
1072         TALLOC_CTX *mem_ctx;
1073
1074         mem_ctx = talloc_init("NTLMSSP Client context");
1075         
1076         *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
1077         if (!*ntlmssp_state) {
1078                 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
1079                 talloc_destroy(mem_ctx);
1080                 return NT_STATUS_NO_MEMORY;
1081         }
1082
1083         (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1084
1085         (*ntlmssp_state)->mem_ctx = mem_ctx;
1086
1087         (*ntlmssp_state)->get_global_myname = global_myname;
1088         (*ntlmssp_state)->get_domain = lp_workgroup;
1089
1090         (*ntlmssp_state)->unicode = True;
1091
1092         (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1093
1094         (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1095
1096         (*ntlmssp_state)->ref_count = 1;
1097
1098         (*ntlmssp_state)->neg_flags = 
1099                 NTLMSSP_NEGOTIATE_128 |
1100                 NTLMSSP_NEGOTIATE_NTLM |
1101                 NTLMSSP_NEGOTIATE_NTLM2 |
1102                 NTLMSSP_NEGOTIATE_KEY_EXCH |
1103                 /*
1104                  * We need to set this to allow a later SetPassword
1105                  * via the SAMR pipe to succeed. Strange.... We could
1106                  * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
1107                  * */
1108                 NTLMSSP_NEGOTIATE_SIGN |
1109                 NTLMSSP_REQUEST_TARGET;
1110
1111         return NT_STATUS_OK;
1112 }
1113