r995: - renamed many of our crypto routines to use the industry standard
[kai/samba-autobuild/.git] / source4 / auth / auth_util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Authentication utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Andrew Bartlett 2001
6    Copyright (C) Jeremy Allison 2000-2001
7    Copyright (C) Rafal Szczesniak 2002
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 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_AUTH
28
29 /****************************************************************************
30  Create an auth_usersupplied_data structure
31 ****************************************************************************/
32 static NTSTATUS make_user_info(auth_usersupplied_info **user_info, 
33                                const char *smb_name, 
34                                const char *internal_username,
35                                const char *client_domain, 
36                                const char *domain,
37                                const char *wksta_name, 
38                                DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
39                                DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
40                                DATA_BLOB *plaintext, 
41                                BOOL encrypted)
42 {
43
44         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
45
46         *user_info = malloc(sizeof(**user_info));
47         if (!user_info) {
48                 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
49                 return NT_STATUS_NO_MEMORY;
50         }
51
52         ZERO_STRUCTP(*user_info);
53
54         DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
55
56         (*user_info)->smb_name.str = strdup(smb_name);
57         if ((*user_info)->smb_name.str) { 
58                 (*user_info)->smb_name.len = strlen(smb_name);
59         } else {
60                 free_user_info(user_info);
61                 return NT_STATUS_NO_MEMORY;
62         }
63         
64         (*user_info)->internal_username.str = strdup(internal_username);
65         if ((*user_info)->internal_username.str) { 
66                 (*user_info)->internal_username.len = strlen(internal_username);
67         } else {
68                 free_user_info(user_info);
69                 return NT_STATUS_NO_MEMORY;
70         }
71
72         (*user_info)->domain.str = strdup(domain);
73         if ((*user_info)->domain.str) { 
74                 (*user_info)->domain.len = strlen(domain);
75         } else {
76                 free_user_info(user_info);
77                 return NT_STATUS_NO_MEMORY;
78         }
79
80         (*user_info)->client_domain.str = strdup(client_domain);
81         if ((*user_info)->client_domain.str) { 
82                 (*user_info)->client_domain.len = strlen(client_domain);
83         } else {
84                 free_user_info(user_info);
85                 return NT_STATUS_NO_MEMORY;
86         }
87
88         (*user_info)->wksta_name.str = strdup(wksta_name);
89         if ((*user_info)->wksta_name.str) { 
90                 (*user_info)->wksta_name.len = strlen(wksta_name);
91         } else {
92                 free_user_info(user_info);
93                 return NT_STATUS_NO_MEMORY;
94         }
95
96         DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
97
98         if (lm_pwd)
99                 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
100         if (nt_pwd)
101                 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
102         if (lm_interactive_pwd)
103                 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
104         if (nt_interactive_pwd)
105                 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
106
107         if (plaintext)
108                 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
109
110         (*user_info)->encrypted = encrypted;
111
112         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
113
114         return NT_STATUS_OK;
115 }
116
117 /****************************************************************************
118  Create an auth_usersupplied_data structure after appropriate mapping.
119 ****************************************************************************/
120
121 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, 
122                             const char *smb_name, 
123                             const char *client_domain, 
124                             const char *wksta_name, 
125                             DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
126                             DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
127                             DATA_BLOB *plaintext, 
128                             BOOL encrypted)
129 {
130         const char *domain;
131         fstring internal_username;
132         fstrcpy(internal_username, smb_name);
133         
134         DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
135               client_domain, smb_name, wksta_name));
136         
137         /* don't allow "" as a domain, fixes a Win9X bug 
138            where it doens't supply a domain for logon script
139            'net use' commands.                                 */
140
141         if ( *client_domain )
142                 domain = client_domain;
143         else
144                 domain = lp_workgroup();
145
146         /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
147         
148         return make_user_info(user_info, smb_name, internal_username, 
149                               client_domain, domain, wksta_name, 
150                               lm_pwd, nt_pwd,
151                               lm_interactive_pwd, nt_interactive_pwd,
152                               plaintext, encrypted);
153 }
154
155 /****************************************************************************
156  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
157  Decrypt and encrypt the passwords.
158 ****************************************************************************/
159
160 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
161                                      const char *smb_name, 
162                                      const char *client_domain, 
163                                      const char *wksta_name, 
164                                      const uint8_t *lm_network_pwd, int lm_pwd_len,
165                                      const uint8_t *nt_network_pwd, int nt_pwd_len)
166 {
167         BOOL ret;
168         NTSTATUS nt_status;
169         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
170         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
171
172         nt_status = make_user_info_map(user_info,
173                                        smb_name, client_domain, 
174                                        wksta_name, 
175                                        lm_pwd_len ? &lm_blob : NULL, 
176                                        nt_pwd_len ? &nt_blob : NULL,
177                                        NULL, NULL, NULL,
178                                        True);
179         
180         ret = NT_STATUS_IS_OK(nt_status) ? True : False;
181                 
182         data_blob_free(&lm_blob);
183         data_blob_free(&nt_blob);
184         return ret;
185 }
186
187 /****************************************************************************
188  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
189  Decrypt and encrypt the passwords.
190 ****************************************************************************/
191
192 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
193                                          const char *smb_name, 
194                                          const char *client_domain, 
195                                          const char *wksta_name, 
196                                          const uint8_t chal[8], 
197                                          const uint8_t lm_interactive_pwd[16], 
198                                          const uint8_t nt_interactive_pwd[16], 
199                                          const uint8_t *dc_sess_key)
200 {
201         char lm_pwd[16];
202         char nt_pwd[16];
203         uint8_t local_lm_response[24];
204         uint8_t local_nt_response[24];
205         uint8_t key[16];
206         
207         ZERO_STRUCT(key);
208         memcpy(key, dc_sess_key, 8);
209         
210         if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
211         if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
212         
213 #ifdef DEBUG_PASSWORD
214         DEBUG(100,("key:"));
215         dump_data(100, (char *)key, sizeof(key));
216         
217         DEBUG(100,("lm owf password:"));
218         dump_data(100, lm_pwd, sizeof(lm_pwd));
219         
220         DEBUG(100,("nt owf password:"));
221         dump_data(100, nt_pwd, sizeof(nt_pwd));
222 #endif
223         
224         if (lm_interactive_pwd)
225                 arcfour_crypt((uint8_t *)lm_pwd, key, sizeof(lm_pwd));
226         
227         if (nt_interactive_pwd)
228                 arcfour_crypt((uint8_t *)nt_pwd, key, sizeof(nt_pwd));
229         
230 #ifdef DEBUG_PASSWORD
231         DEBUG(100,("decrypt of lm owf password:"));
232         dump_data(100, lm_pwd, sizeof(lm_pwd));
233         
234         DEBUG(100,("decrypt of nt owf password:"));
235         dump_data(100, nt_pwd, sizeof(nt_pwd));
236 #endif
237         
238         if (lm_interactive_pwd)
239                 SMBOWFencrypt((const uint8_t *)lm_pwd, chal, local_lm_response);
240
241         if (nt_interactive_pwd)
242                 SMBOWFencrypt((const uint8_t *)nt_pwd, chal, local_nt_response);
243         
244         /* Password info paranoia */
245         ZERO_STRUCT(key);
246
247         {
248                 BOOL ret;
249                 NTSTATUS nt_status;
250                 DATA_BLOB local_lm_blob;
251                 DATA_BLOB local_nt_blob;
252
253                 DATA_BLOB lm_interactive_blob;
254                 DATA_BLOB nt_interactive_blob;
255                 
256                 if (lm_interactive_pwd) {
257                         local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
258                         lm_interactive_blob = data_blob(lm_pwd, sizeof(lm_pwd));
259                         ZERO_STRUCT(lm_pwd);
260                 }
261                 
262                 if (nt_interactive_pwd) {
263                         local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
264                         nt_interactive_blob = data_blob(nt_pwd, sizeof(nt_pwd));
265                         ZERO_STRUCT(nt_pwd);
266                 }
267
268                 nt_status = make_user_info_map(user_info, 
269                                                smb_name, client_domain, 
270                                                wksta_name, 
271                                                lm_interactive_pwd ? &local_lm_blob : NULL,
272                                                nt_interactive_pwd ? &local_nt_blob : NULL,
273                                                lm_interactive_pwd ? &lm_interactive_blob : NULL,
274                                                nt_interactive_pwd ? &nt_interactive_blob : NULL,
275                                                NULL,
276                                                True);
277
278                 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
279                 data_blob_free(&local_lm_blob);
280                 data_blob_free(&local_nt_blob);
281                 data_blob_free(&lm_interactive_blob);
282                 data_blob_free(&nt_interactive_blob);
283                 return ret;
284         }
285 }
286
287
288 /****************************************************************************
289  Create an auth_usersupplied_data structure
290 ****************************************************************************/
291
292 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
293                               const char *smb_name, 
294                               const char *client_domain,
295                               const uint8_t chal[8],
296                               DATA_BLOB plaintext_password)
297 {
298
299         DATA_BLOB local_lm_blob;
300         DATA_BLOB local_nt_blob;
301         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
302                         
303         /*
304          * Not encrypted - do so.
305          */
306         
307         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
308         
309         if (plaintext_password.data) {
310                 uint8_t local_lm_response[24];
311                 
312 #ifdef DEBUG_PASSWORD
313                 DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
314                 dump_data(100, plaintext_password.data, plaintext_password.length);
315 #endif
316
317                 SMBencrypt( (const char *)plaintext_password.data, (const uint8_t *)chal, local_lm_response);
318                 local_lm_blob = data_blob(local_lm_response, 24);
319                 
320                 /* We can't do an NT hash here, as the password needs to be
321                    case insensitive */
322                 local_nt_blob = data_blob(NULL, 0); 
323                 
324         } else {
325                 local_lm_blob = data_blob(NULL, 0); 
326                 local_nt_blob = data_blob(NULL, 0); 
327         }
328         
329         ret = make_user_info_map(user_info, smb_name,
330                                  client_domain, 
331                                  sub_get_remote_machine(),
332                                  local_lm_blob.data ? &local_lm_blob : NULL,
333                                  local_nt_blob.data ? &local_nt_blob : NULL,
334                                  NULL, NULL,
335                                  plaintext_password.data ? &plaintext_password : NULL, 
336                                  False);
337         
338         data_blob_free(&local_lm_blob);
339         return NT_STATUS_IS_OK(ret) ? True : False;
340 }
341
342 /****************************************************************************
343  Create an auth_usersupplied_data structure
344 ****************************************************************************/
345
346 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
347                                       const char *smb_name,
348                                       const char *client_domain, 
349                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
350 {
351         return make_user_info_map(user_info, smb_name, 
352                                   client_domain, 
353                                   sub_get_remote_machine(), 
354                                   lm_resp.data ? &lm_resp : NULL, 
355                                   nt_resp.data ? &nt_resp : NULL, 
356                                   NULL, NULL, NULL,
357                                   True);
358 }
359
360 /****************************************************************************
361  Create a guest user_info blob, for anonymous authenticaion.
362 ****************************************************************************/
363
364 BOOL make_user_info_guest(auth_usersupplied_info **user_info) 
365 {
366         NTSTATUS nt_status;
367
368         nt_status = make_user_info(user_info, 
369                                    "","", 
370                                    "","", 
371                                    "", 
372                                    NULL, NULL, 
373                                    NULL, NULL, 
374                                    NULL,
375                                    True);
376                               
377         return NT_STATUS_IS_OK(nt_status) ? True : False;
378 }
379
380 /****************************************************************************
381  prints a NT_USER_TOKEN to debug output.
382 ****************************************************************************/
383
384 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
385 {
386         TALLOC_CTX *mem_ctx;
387
388         size_t     i;
389         
390         if (!token) {
391                 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
392                 return;
393         }
394         
395         mem_ctx = talloc_init("debug_nt_user_token()");
396         if (!mem_ctx) {
397                 return;
398         }
399
400         DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n",
401                                     dom_sid_string(mem_ctx, token->user_sids[0]) ));
402         DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids));
403         for (i = 0; i < token->num_sids; i++)
404                 DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i, 
405                                                dom_sid_string(mem_ctx, token->user_sids[i])));
406
407         talloc_destroy(mem_ctx);
408 }
409
410 /****************************************************************************
411  Create the SID list for this user.
412 ****************************************************************************/
413
414 NTSTATUS create_nt_user_token(TALLOC_CTX *mem_ctx, 
415                               struct dom_sid *user_sid, struct dom_sid *group_sid, 
416                               int n_groupSIDs, struct dom_sid **groupSIDs, 
417                               BOOL is_guest, struct nt_user_token **token)
418 {
419         NTSTATUS       nt_status = NT_STATUS_OK;
420         struct nt_user_token *ptoken;
421         int i;
422         int sid_ndx;
423         
424         if (!(ptoken = talloc_p(mem_ctx, struct nt_user_token))) {
425                 DEBUG(0, ("create_nt_token: Out of memory allocating token\n"));
426                 nt_status = NT_STATUS_NO_MEMORY;
427                 return nt_status;
428         }
429
430         ptoken->num_sids = 0;
431
432         if (!(ptoken->user_sids = talloc_array_p(mem_ctx, struct dom_sid*, n_groupSIDs + 5))) {
433                 DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n"));
434                 nt_status = NT_STATUS_NO_MEMORY;
435                 return nt_status;
436         }
437         
438         /*
439          * Note - user SID *MUST* be first in token !
440          * se_access_check depends on this.
441          *
442          * Primary group SID is second in token. Convention.
443          */
444
445         ptoken->user_sids[PRIMARY_USER_SID_INDEX] = user_sid;
446         ptoken->num_sids++;
447         ptoken->user_sids[PRIMARY_GROUP_SID_INDEX] = group_sid;
448         ptoken->num_sids++;
449
450         /*
451          * Finally add the "standard" SIDs.
452          * The only difference between guest and "anonymous" (which we
453          * don't really support) is the addition of Authenticated_Users.
454          */
455         ptoken->user_sids[2] = dom_sid_parse_talloc(mem_ctx, SID_WORLD);
456         ptoken->user_sids[3] = dom_sid_parse_talloc(mem_ctx, SID_NETWORK);
457
458         if (is_guest) {
459                 ptoken->user_sids[4] = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN_GUESTS);
460                 ptoken->num_sids++;
461         } else {
462                 ptoken->user_sids[4] = dom_sid_parse_talloc(mem_ctx, SID_AUTHENTICATED_USERS);
463                 ptoken->num_sids++;
464         }
465
466         sid_ndx = 5; /* next available spot */
467
468         for (i = 0; i < n_groupSIDs; i++) {
469                 size_t check_sid_idx;
470                 for (check_sid_idx = 1; check_sid_idx < ptoken->num_sids; check_sid_idx++) {
471                         if (sid_equal(ptoken->user_sids[check_sid_idx], 
472                                       groupSIDs[i])) {
473                                 break;
474                         }
475                 }
476                 
477                 if (check_sid_idx >= ptoken->num_sids) /* Not found already */ {
478                         ptoken->user_sids[sid_ndx++] = groupSIDs[i];
479                         ptoken->num_sids++;
480                 }
481         }
482         
483         debug_nt_user_token(DBGC_AUTH, 10, ptoken);
484         
485         *token = ptoken;
486
487         return nt_status;
488 }
489
490 /***************************************************************************
491  Make a user_info struct
492 ***************************************************************************/
493
494 NTSTATUS make_server_info(auth_serversupplied_info **server_info, const char *username)
495 {
496         TALLOC_CTX *mem_ctx = talloc_init("auth subsystem: server_info for %s", username);
497         *server_info = talloc_p(mem_ctx, auth_serversupplied_info);
498         if (!*server_info) {
499                 DEBUG(0,("make_server_info: malloc failed!\n"));
500                 talloc_destroy(mem_ctx);
501                 return NT_STATUS_NO_MEMORY;
502         }
503         (*server_info)->mem_ctx = mem_ctx;
504         
505         return NT_STATUS_OK;
506 }
507
508 /***************************************************************************
509  Make (and fill) a user_info struct for a guest login.
510 ***************************************************************************/
511 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
512 {
513         NTSTATUS nt_status;
514         static const char zeros[16];
515         struct dom_sid *sid_Anonymous;
516         struct dom_sid *sid_Builtin_Guests;
517
518         nt_status = make_server_info(server_info, "");
519
520         if (!NT_STATUS_IS_OK(nt_status)) {
521                 return nt_status;
522         }
523         
524         (*server_info)->guest = True;
525
526         sid_Anonymous = dom_sid_parse_talloc((*server_info)->mem_ctx, SID_ANONYMOUS);
527         sid_Builtin_Guests = dom_sid_parse_talloc((*server_info)->mem_ctx, SID_BUILTIN_GUESTS);
528         
529         if (!NT_STATUS_IS_OK(nt_status = create_nt_user_token((*server_info)->mem_ctx, 
530                                                               sid_Anonymous, sid_Builtin_Guests,
531                                                               0, NULL, 
532                                                               True, &(*server_info)->ptok))) {
533                 DEBUG(1,("check_sam_security: create_nt_user_token failed with '%s'\n", nt_errstr(nt_status)));
534                 free_server_info(server_info);
535                 return nt_status;
536         }
537         
538         /* annoying, but the Guest really does have a session key, 
539            and it is all zeros! */
540         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
541         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
542
543         return nt_status;
544 }
545
546 /***************************************************************************
547  Free a user_info struct
548 ***************************************************************************/
549
550 void free_user_info(auth_usersupplied_info **user_info)
551 {
552         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
553         if (*user_info != NULL) {
554                 if ((*user_info)->smb_name.str) {
555                         DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
556                 }
557                 SAFE_FREE((*user_info)->smb_name.str);
558                 SAFE_FREE((*user_info)->internal_username.str);
559                 SAFE_FREE((*user_info)->client_domain.str);
560                 SAFE_FREE((*user_info)->domain.str);
561                 SAFE_FREE((*user_info)->wksta_name.str);
562                 data_blob_free(&(*user_info)->lm_resp);
563                 data_blob_free(&(*user_info)->nt_resp);
564                 data_blob_clear_free(&(*user_info)->plaintext_password);
565                 ZERO_STRUCT(**user_info);
566         }
567         SAFE_FREE(*user_info);
568 }
569
570 /***************************************************************************
571  Clear out a server_info struct that has been allocated
572 ***************************************************************************/
573
574 void free_server_info(auth_serversupplied_info **server_info)
575 {
576         DEBUG(5,("attempting to free a server_info structure\n"));
577         if (!*server_info) {
578                 talloc_destroy((*server_info)->mem_ctx);
579         }
580         *server_info = NULL;
581 }
582
583 /***************************************************************************
584  Make an auth_methods struct
585 ***************************************************************************/
586
587 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
588 {
589         if (!auth_context) {
590                 smb_panic("no auth_context supplied to make_auth_methods()!\n");
591         }
592
593         if (!auth_method) {
594                 smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
595         }
596
597         *auth_method = talloc(auth_context->mem_ctx, sizeof(**auth_method));
598         if (!*auth_method) {
599                 DEBUG(0,("make_auth_method: malloc failed!\n"));
600                 return False;
601         }
602         ZERO_STRUCTP(*auth_method);
603         
604         return True;
605 }
606
607 /****************************************************************************
608  Delete a SID token.
609 ****************************************************************************/
610
611 void delete_nt_token(NT_USER_TOKEN **pptoken)
612 {
613     if (*pptoken) {
614             NT_USER_TOKEN *ptoken = *pptoken;
615             SAFE_FREE( ptoken->user_sids );
616             ZERO_STRUCTP(ptoken);
617     }
618     SAFE_FREE(*pptoken);
619 }
620
621 /**
622  * Squash an NT_STATUS in line with security requirements.
623  * In an attempt to avoid giving the whole game away when users
624  * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and 
625  * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations 
626  * (session setups in particular).
627  *
628  * @param nt_status NTSTATUS input for squashing.
629  * @return the 'squashed' nt_status
630  **/
631
632 NTSTATUS nt_status_squash(NTSTATUS nt_status)
633 {
634         if NT_STATUS_IS_OK(nt_status) {
635                 return nt_status;               
636         } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
637                 /* Match WinXP and don't give the game away */
638                 return NT_STATUS_LOGON_FAILURE;
639                 
640         } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
641                 /* Match WinXP and don't give the game away */
642                 return NT_STATUS_LOGON_FAILURE;
643         } else {
644                 return nt_status;
645         }  
646 }
647
648
649