This is another rather major change to the samba authenticaion
[ira/wip.git] / source3 / smbd / auth_util.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Authentication utility functions
5    Copyright (C) Andrew Tridgell 1992-1998
6    Copyright (C) Andrew Bartlett 2001
7    Copyright (C) Jeremy Allison 2000-2001
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 extern fstring remote_machine;
27 extern pstring global_myname;
28
29 /****************************************************************************
30  Create a UNIX user on demand.
31 ****************************************************************************/
32
33 static int smb_create_user(const char *unix_user, const char *homedir)
34 {
35         pstring add_script;
36         int ret;
37
38         pstrcpy(add_script, lp_adduser_script());
39         if (! *add_script)
40                 return -1;
41         all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
42         if (homedir)
43                 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
44         ret = smbrun(add_script,NULL);
45         DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
46         return ret;
47 }
48
49 /****************************************************************************
50  Delete a UNIX user on demand.
51 ****************************************************************************/
52
53 static int smb_delete_user(char *unix_user)
54 {
55         pstring del_script;
56         int ret;
57
58         pstrcpy(del_script, lp_deluser_script());
59         if (! *del_script)
60                 return -1;
61         all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
62         ret = smbrun(del_script,NULL);
63         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
64         return ret;
65 }
66
67 /****************************************************************************
68  Add and Delete UNIX users on demand, based on NTSTATUS codes.
69 ****************************************************************************/
70
71 void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status) 
72 {
73         struct passwd *pwd=NULL;
74
75         if (NT_STATUS_IS_OK(nt_status)) {
76
77                 if (!(server_info->sam_fill_level & SAM_FILL_UNIX)) {
78                         
79                         /*
80                          * User validated ok against Domain controller.
81                          * If the admin wants us to try and create a UNIX
82                          * user on the fly, do so.
83                          */
84                         
85                         if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) {
86                                 smb_create_user(user_info->internal_username.str, NULL);
87                         }
88                 } else {                        
89                         if(lp_adduser_script()) {
90                                 SMB_STRUCT_STAT st;
91                                 const char *home_dir = pdb_get_homedir(server_info->sam_account);
92                                 /*
93                                  * Also call smb_create_user if the users
94                                  * home directory doesn't exist. Used with
95                                  * winbindd to allow the script to create
96                                  * the home directory for a user mapped
97                                  * with winbindd.
98                                  */
99
100                                 if (home_dir && 
101                                     (sys_stat(home_dir, &st) == -1) && (errno == ENOENT)) {
102                                                 smb_create_user(user_info->internal_username.str, home_dir);
103                                 }
104                         }
105                 }
106         } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
107                 /*
108                  * User failed to validate ok against Domain controller.
109                  * If the failure was "user doesn't exist" and admin 
110                  * wants us to try and delete that UNIX user on the fly,
111                  * do so.
112                  */
113                 if (lp_deluser_script()) {
114                         smb_delete_user(user_info->internal_username.str);
115                 }
116         }
117 }
118
119 /****************************************************************************
120  Create an auth_usersupplied_data structure
121 ****************************************************************************/
122
123 static BOOL make_user_info(auth_usersupplied_info **user_info, 
124                            const char *smb_name, 
125                            const char *internal_username,
126                            const char *client_domain, 
127                            const char *domain,
128                            const char *wksta_name, 
129                            DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
130                            DATA_BLOB plaintext, 
131                            uint32 ntlmssp_flags, BOOL encrypted)
132 {
133
134         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
135
136         *user_info = malloc(sizeof(**user_info));
137         if (!user_info) {
138                 DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info)));
139                 return False;
140         }
141
142         ZERO_STRUCTP(*user_info);
143
144         DEBUG(5,("makeing strings for %s's user_info struct\n", internal_username));
145
146         (*user_info)->smb_name.str = strdup(smb_name);
147         if ((*user_info)->smb_name.str) { 
148                 (*user_info)->smb_name.len = strlen(smb_name);
149         } else {
150                 free_user_info(user_info);
151                 return False;
152         }
153         
154         (*user_info)->internal_username.str = strdup(internal_username);
155         if ((*user_info)->internal_username.str) { 
156                 (*user_info)->internal_username.len = strlen(internal_username);
157         } else {
158                 free_user_info(user_info);
159                 return False;
160         }
161
162         (*user_info)->domain.str = strdup(domain);
163         if ((*user_info)->domain.str) { 
164                 (*user_info)->domain.len = strlen(domain);
165         } else {
166                 free_user_info(user_info);
167                 return False;
168         }
169
170         (*user_info)->client_domain.str = strdup(client_domain);
171         if ((*user_info)->client_domain.str) { 
172                 (*user_info)->client_domain.len = strlen(client_domain);
173         } else {
174                 free_user_info(user_info);
175                 return False;
176         }
177
178         (*user_info)->wksta_name.str = strdup(wksta_name);
179         if ((*user_info)->wksta_name.str) { 
180                 (*user_info)->wksta_name.len = strlen(wksta_name);
181         } else {
182                 free_user_info(user_info);
183                 return False;
184         }
185
186         DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username));
187
188         (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length);
189         (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length);
190         (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
191
192         (*user_info)->encrypted = encrypted;
193         (*user_info)->ntlmssp_flags = ntlmssp_flags;
194
195         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
196
197         return True;
198 }
199
200 /****************************************************************************
201  Create an auth_usersupplied_data structure after appropriate mapping.
202 ****************************************************************************/
203
204 BOOL make_user_info_map(auth_usersupplied_info **user_info, 
205                         const char *smb_name, 
206                         const char *client_domain, 
207                         const char *wksta_name, 
208                         DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
209                         DATA_BLOB plaintext, 
210                         uint32 ntlmssp_flags, BOOL encrypted)
211 {
212         const char *domain;
213         fstring internal_username;
214         fstrcpy(internal_username, smb_name);
215         map_username(internal_username); 
216         
217         if (lp_allow_trusted_domains()) {
218                 domain = client_domain;
219         } else {
220                 domain = lp_workgroup();
221         }
222         
223         return make_user_info(user_info, 
224                               smb_name, internal_username,
225                               client_domain, domain,
226                               wksta_name, 
227                               lm_pwd, nt_pwd,
228                               plaintext, 
229                               ntlmssp_flags, encrypted);
230         
231 }
232
233 /****************************************************************************
234  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
235  Decrypt and encrypt the passwords.
236 ****************************************************************************/
237
238 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
239                                      char *smb_name, 
240                                      char *client_domain, 
241                                      char *wksta_name, 
242                                      uchar *lm_network_pwd, int lm_pwd_len,
243                                      uchar *nt_network_pwd, int nt_pwd_len)
244 {
245         BOOL ret;
246         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
247         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
248         DATA_BLOB plaintext_blob = data_blob(NULL, 0);
249         uint32 ntlmssp_flags = 0;
250
251         if (lm_pwd_len)
252                 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
253         if (nt_pwd_len == 24) {
254                 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; 
255         } else if (nt_pwd_len != 0) {
256                 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2; 
257         }
258
259         ret = make_user_info_map(user_info, 
260                                  smb_name, client_domain, 
261                                  wksta_name, 
262                                  lm_blob, nt_blob,
263                                  plaintext_blob, 
264                                  ntlmssp_flags, True);
265                 
266         data_blob_free(&lm_blob);
267         data_blob_free(&nt_blob);
268         return ret;
269 }
270
271 /****************************************************************************
272  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
273  Decrypt and encrypt the passwords.
274 ****************************************************************************/
275
276 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
277                                          char *smb_name, 
278                                          char *client_domain, 
279                                          char *wksta_name, 
280                                          char chal[8], 
281                                          uchar lm_interactive_pwd[16], 
282                                          uchar nt_interactive_pwd[16], 
283                                          uchar *dc_sess_key)
284 {
285         char lm_pwd[16];
286         char nt_pwd[16];
287         unsigned char local_lm_response[24];
288         unsigned char local_nt_response[24];
289         unsigned char key[16];
290         uint32 ntlmssp_flags = 0;
291         
292         ZERO_STRUCT(key);
293         memcpy(key, dc_sess_key, 8);
294         
295         if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
296         if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
297         
298 #ifdef DEBUG_PASSWORD
299         DEBUG(100,("key:"));
300         dump_data(100, (char *)key, sizeof(key));
301         
302         DEBUG(100,("lm owf password:"));
303         dump_data(100, lm_pwd, sizeof(lm_pwd));
304         
305         DEBUG(100,("nt owf password:"));
306         dump_data(100, nt_pwd, sizeof(nt_pwd));
307 #endif
308         
309         SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
310         SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
311         
312 #ifdef DEBUG_PASSWORD
313         DEBUG(100,("decrypt of lm owf password:"));
314         dump_data(100, lm_pwd, sizeof(lm_pwd));
315         
316         DEBUG(100,("decrypt of nt owf password:"));
317         dump_data(100, nt_pwd, sizeof(nt_pwd));
318 #endif
319         
320         SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
321         SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
322         
323         /* Password info parinoia */
324         ZERO_STRUCT(lm_pwd);
325         ZERO_STRUCT(nt_pwd);
326         ZERO_STRUCT(key);
327
328         {
329                 BOOL ret;
330                 DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
331                 DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
332                 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
333
334                 if (lm_interactive_pwd)
335                         ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
336                 if (nt_interactive_pwd)
337                         ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; 
338
339                 ret = make_user_info_map(user_info, 
340                                          smb_name, client_domain, 
341                                          wksta_name, 
342                                          local_lm_blob,
343                                          local_nt_blob,
344                                          plaintext_blob, 
345                                          ntlmssp_flags, True);
346                 
347                 data_blob_free(&local_lm_blob);
348                 data_blob_free(&local_nt_blob);
349                 return ret;
350         }
351 }
352
353 /****************************************************************************
354  Create an auth_usersupplied_data structure
355 ****************************************************************************/
356
357 BOOL make_user_info_winbind(auth_usersupplied_info **user_info, 
358                             const char *username,
359                             const char *domain, 
360                             const char *password,
361                             char chal[8] /* Give winbind back the challange we used */
362         )
363 {
364         unsigned char local_lm_response[24];
365         unsigned char local_nt_response[24];
366         DATA_BLOB local_lm_blob;
367         DATA_BLOB local_nt_blob;
368         DATA_BLOB plaintext_blob;
369         uint32 ntlmssp_flags = 0;
370
371         /*
372          * Not encrypted - do so.
373          */
374         
375         DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
376         
377         generate_random_buffer(chal, 8, False);
378
379         if (*password) {
380                 SMBencrypt( (const uchar *)password, chal, local_lm_response);
381                 
382                 /* This encrypts the lm_pwd field, which actually contains
383                    the password rather than the nt_pwd field because that
384                    contains nothing */
385                 
386                 /* WATCH OUT. This doesn't work if the incoming password is
387                    incorrectly cased.  We might want to add a check here
388                    and only do an LM in that case */
389                 
390                 SMBNTencrypt((const uchar *)password, chal, local_nt_response);
391
392                 local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
393                 local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
394                 plaintext_blob = data_blob(password, strlen(password)+1);
395                 if ((!local_lm_blob.data) || (!local_nt_blob.data)|| (!plaintext_blob.data)) {
396                         data_blob_free(&local_lm_blob);
397                         data_blob_free(&local_nt_blob);
398                         data_blob_clear_free(&plaintext_blob);
399                         return False;
400                 }
401                 ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;
402         } else {
403                 local_lm_blob = data_blob(NULL, 0);
404                 local_nt_blob = data_blob(NULL, 0);
405                 plaintext_blob = data_blob(NULL, 0);
406         }
407
408         {
409                 BOOL ret;
410
411                 ret = make_user_info(user_info, 
412                                      username, username,
413                                      domain, domain, 
414                                      global_myname, 
415                                      local_nt_blob,
416                                      local_lm_blob,
417                                      plaintext_blob, 
418                                      ntlmssp_flags, False);
419                 
420                 data_blob_free(&local_lm_blob);
421                 data_blob_free(&local_nt_blob);
422                 data_blob_clear_free(&plaintext_blob);
423                 return ret;
424         }
425 }
426
427 /****************************************************************************
428  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
429  Decrypt and encrypt the passwords.
430 ****************************************************************************/
431
432 BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info, 
433                                  char *smb_name, 
434                                  char *client_domain, 
435                                  uchar *lm_network_pwd, int lm_pwd_len,
436                                  uchar *nt_network_pwd, int nt_pwd_len)
437 {
438         BOOL ret;
439         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
440         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
441         DATA_BLOB plaintext_blob = data_blob(NULL, 0);
442         uint32 ntlmssp_flags = 0;
443
444         if (lm_pwd_len)
445                 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
446         if (nt_pwd_len)
447                 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; 
448         
449         ret = make_user_info(user_info, 
450                              smb_name, smb_name, 
451                              client_domain, client_domain, 
452                              global_myname, 
453                              nt_blob, lm_blob,
454                              plaintext_blob, 
455                              ntlmssp_flags, True);
456
457         data_blob_free(&lm_blob);
458         data_blob_free(&nt_blob);
459         return ret;
460 }
461
462 /****************************************************************************
463  Create an auth_usersupplied_data structure
464 ****************************************************************************/
465
466 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
467                               char *smb_name, 
468                               char *client_domain,
469                               char chal[8],
470                               DATA_BLOB plaintext_password)
471 {
472
473         DATA_BLOB local_lm_blob;
474         DATA_BLOB local_nt_blob;
475         BOOL ret = False;
476         uint32 ntlmssp_flags = 0;
477                         
478         /*
479          * Not encrypted - do so.
480          */
481         
482         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
483         
484         if (plaintext_password.data) {
485                 unsigned char local_lm_response[24];
486                 
487 #ifdef DEBUG_PASSWORD
488                 DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
489                 dump_data(100, plaintext_password.data, plaintext_password.length);
490 #endif
491
492                 SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
493                 local_lm_blob = data_blob(local_lm_response, 24);
494                 
495                 /* We can't do an NT hash here, as the password needs to be
496                    case insensitive */
497                 local_nt_blob = data_blob(NULL, 0); 
498                 
499                 ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM;
500         } else {
501                 local_lm_blob = data_blob(NULL, 0); 
502                 local_nt_blob = data_blob(NULL, 0); 
503         }
504         
505         ret = make_user_info_map(user_info, smb_name,
506                                  client_domain, 
507                                  remote_machine,
508                                  local_lm_blob,
509                                  local_nt_blob,
510                                  plaintext_password, 
511                                  ntlmssp_flags, False);
512         
513         data_blob_free(&local_lm_blob);
514         return ret;
515 }
516
517 /****************************************************************************
518  Create an auth_usersupplied_data structure
519 ****************************************************************************/
520
521 BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
522                               char *smb_name,
523                               char *client_domain, 
524                               DATA_BLOB lm_resp, DATA_BLOB nt_resp,
525                               DATA_BLOB plaintext_password)
526 {
527         uint32 ntlmssp_flags = 0;
528
529         DATA_BLOB no_plaintext_blob = data_blob(NULL, 0); 
530         
531         if (lm_resp.length == 24) {
532                 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
533         }
534         if (nt_resp.length == 0) {
535         } else if (nt_resp.length == 24) {
536                 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
537         } else {
538                 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
539         }
540
541         return make_user_info_map(user_info, smb_name, 
542                                  client_domain, 
543                                  remote_machine, 
544                                  lm_resp, 
545                                  nt_resp, 
546                                  no_plaintext_blob, 
547                                  ntlmssp_flags, True);
548 }
549
550 /****************************************************************************
551  Create a guest user_info blob, for anonymous authenticaion.
552 ****************************************************************************/
553
554 BOOL make_user_info_guest(auth_usersupplied_info **user_info) 
555 {
556         DATA_BLOB lm_blob = data_blob(NULL, 0);
557         DATA_BLOB nt_blob = data_blob(NULL, 0);
558         DATA_BLOB plaintext_blob = data_blob(NULL, 0);
559         uint32 ntlmssp_flags = 0;
560
561         return make_user_info(user_info, 
562                               "","", 
563                               "","", 
564                               "", 
565                               nt_blob, lm_blob,
566                               plaintext_blob, 
567                               ntlmssp_flags, True);
568 }
569
570 /***************************************************************************
571  Make a user_info struct
572 ***************************************************************************/
573
574 BOOL make_server_info(auth_serversupplied_info **server_info) 
575 {
576         *server_info = malloc(sizeof(**server_info));
577         if (!*server_info) {
578                 DEBUG(0,("make_server_info: malloc failed!\n"));
579                 return False;
580         }
581         ZERO_STRUCTP(*server_info);
582         return True;
583 }
584
585 /***************************************************************************
586  Make (and fill) a user_info struct from a SAM_ACCOUNT
587 ***************************************************************************/
588
589 BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass) 
590 {
591         if (!make_server_info(server_info)) {
592                 return False;
593         }
594
595         (*server_info)->sam_fill_level = SAM_FILL_ALL;
596         (*server_info)->sam_account = sampass;
597
598         DEBUG(5,("make_server_info_sam: made server info for user %s\n",
599                  pdb_get_username((*server_info)->sam_account)));
600         return True;
601 }
602
603 /***************************************************************************
604  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
605  to a SAM_ACCOUNT
606 ***************************************************************************/
607
608 BOOL make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd)
609 {
610         SAM_ACCOUNT *sampass = NULL;
611         if (!pdb_init_sam_pw(&sampass, pwd)) {          
612                 return False;
613         }
614         return make_server_info_sam(server_info, sampass);
615 }
616
617 /***************************************************************************
618  Free a user_info struct
619 ***************************************************************************/
620
621 void free_user_info(auth_usersupplied_info **user_info)
622 {
623         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
624         if (*user_info != NULL) {
625                 if ((*user_info)->smb_name.str) {
626                         DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
627                 }
628                 SAFE_FREE((*user_info)->smb_name.str);
629                 SAFE_FREE((*user_info)->internal_username.str);
630                 SAFE_FREE((*user_info)->client_domain.str);
631                 SAFE_FREE((*user_info)->domain.str);
632                 data_blob_free(&(*user_info)->lm_resp);
633                 data_blob_free(&(*user_info)->nt_resp);
634                 SAFE_FREE((*user_info)->interactive_password);
635                 data_blob_clear_free(&(*user_info)->plaintext_password);
636                 ZERO_STRUCT(**user_info);
637         }
638         SAFE_FREE(*user_info);
639 }
640
641 /***************************************************************************
642  Clear out a server_info struct that has been allocated
643 ***************************************************************************/
644
645 void free_server_info(auth_serversupplied_info **server_info)
646 {
647         if (*server_info != NULL) {
648                 pdb_free_sam(&(*server_info)->sam_account);
649                 
650                 /* call pam_end here, unless we know we are keeping it */
651                 delete_nt_token( &(*server_info)->ptok );
652                 ZERO_STRUCT(**server_info);
653         }
654         SAFE_FREE(*server_info);
655 }
656
657 /***************************************************************************
658  Make a server_info struct for a guest user 
659 ***************************************************************************/
660
661 BOOL make_server_info_guest(auth_serversupplied_info **server_info) 
662 {
663         struct passwd *pass = sys_getpwnam(lp_guestaccount());
664         
665         if (pass) {
666                 if (!make_server_info_pw(server_info, pass)) {
667                         return False;
668                 }
669                 (*server_info)->guest = True;
670                 return True;
671         }
672         DEBUG(0,("make_server_info_guest: sys_getpwnam() failed on guest account!\n")); 
673         return False;
674 }
675
676 /***************************************************************************
677  Make an auth_methods struct
678 ***************************************************************************/
679
680 BOOL make_auth_methods(auth_methods **auth_method) 
681 {
682         *auth_method = malloc(sizeof(**auth_method));
683         if (!*auth_method) {
684                 DEBUG(0,("make_auth_method: malloc failed!\n"));
685                 return False;
686         }
687         ZERO_STRUCTP(*auth_method);
688         
689         return True;
690 }
691
692 /****************************************************************************
693  Delete a SID token.
694 ****************************************************************************/
695
696 void delete_nt_token(NT_USER_TOKEN **pptoken)
697 {
698     if (*pptoken) {
699                 NT_USER_TOKEN *ptoken = *pptoken;
700         SAFE_FREE( ptoken->user_sids );
701         ZERO_STRUCTP(ptoken);
702     }
703     SAFE_FREE(*pptoken);
704 }
705
706 /****************************************************************************
707  Duplicate a SID token.
708 ****************************************************************************/
709
710 NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
711 {
712         NT_USER_TOKEN *token;
713
714         if (!ptoken)
715                 return NULL;
716
717     if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
718         return NULL;
719
720     ZERO_STRUCTP(token);
721
722     if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
723         SAFE_FREE(token);
724         return NULL;
725     }
726
727     token->num_sids = ptoken->num_sids;
728
729         return token;
730 }