Merge branch 'v3-devel' of ssh://git.samba.org/data/git/samba into v3-devel
[samba.git] / source3 / 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    Copyright (C) Volker Lendecke 2006
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_AUTH
28
29 /****************************************************************************
30  Ensure primary group SID is always at position 0 in a 
31  auth_serversupplied_info struct.
32 ****************************************************************************/
33
34 static void sort_sid_array_for_smbd(auth_serversupplied_info *result,
35                                 const DOM_SID *pgroup_sid)
36 {
37         unsigned int i;
38
39         if (!result->sids) {
40                 return;
41         }
42
43         if (sid_compare(&result->sids[0], pgroup_sid)==0) {
44                 return;
45         }
46
47         for (i = 1; i < result->num_sids; i++) {
48                 if (sid_compare(pgroup_sid,
49                                 &result->sids[i]) == 0) {
50                         sid_copy(&result->sids[i], &result->sids[0]);
51                         sid_copy(&result->sids[0], pgroup_sid);
52                         return;
53                 }
54         }
55 }
56
57 /****************************************************************************
58  Create a UNIX user on demand.
59 ****************************************************************************/
60
61 static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
62 {
63         TALLOC_CTX *ctx = talloc_tos();
64         char *add_script;
65         int ret;
66
67         add_script = talloc_strdup(ctx, lp_adduser_script());
68         if (!add_script || !*add_script) {
69                 return -1;
70         }
71         add_script = talloc_all_string_sub(ctx,
72                                 add_script,
73                                 "%u",
74                                 unix_username);
75         if (!add_script) {
76                 return -1;
77         }
78         if (domain) {
79                 add_script = talloc_all_string_sub(ctx,
80                                         add_script,
81                                         "%D",
82                                         domain);
83                 if (!add_script) {
84                         return -1;
85                 }
86         }
87         if (homedir) {
88                 add_script = talloc_all_string_sub(ctx,
89                                 add_script,
90                                 "%H",
91                                 homedir);
92                 if (!add_script) {
93                         return -1;
94                 }
95         }
96         ret = smbrun(add_script,NULL);
97         flush_pwnam_cache();
98         DEBUG(ret ? 0 : 3,
99                 ("smb_create_user: Running the command `%s' gave %d\n",
100                  add_script,ret));
101         return ret;
102 }
103
104 /****************************************************************************
105  Create an auth_usersupplied_data structure
106 ****************************************************************************/
107
108 static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
109                                const char *smb_name,
110                                const char *internal_username,
111                                const char *client_domain,
112                                const char *domain,
113                                const char *wksta_name,
114                                DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
115                                DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
116                                DATA_BLOB *plaintext,
117                                bool encrypted)
118 {
119
120         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
121
122         *user_info = SMB_MALLOC_P(auth_usersupplied_info);
123         if (*user_info == NULL) {
124                 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
125                 return NT_STATUS_NO_MEMORY;
126         }
127
128         ZERO_STRUCTP(*user_info);
129
130         DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
131
132         (*user_info)->smb_name = SMB_STRDUP(smb_name);
133         if ((*user_info)->smb_name == NULL) { 
134                 free_user_info(user_info);
135                 return NT_STATUS_NO_MEMORY;
136         }
137         
138         (*user_info)->internal_username = SMB_STRDUP(internal_username);
139         if ((*user_info)->internal_username == NULL) { 
140                 free_user_info(user_info);
141                 return NT_STATUS_NO_MEMORY;
142         }
143
144         (*user_info)->domain = SMB_STRDUP(domain);
145         if ((*user_info)->domain == NULL) { 
146                 free_user_info(user_info);
147                 return NT_STATUS_NO_MEMORY;
148         }
149
150         (*user_info)->client_domain = SMB_STRDUP(client_domain);
151         if ((*user_info)->client_domain == NULL) { 
152                 free_user_info(user_info);
153                 return NT_STATUS_NO_MEMORY;
154         }
155
156         (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
157         if ((*user_info)->wksta_name == NULL) { 
158                 free_user_info(user_info);
159                 return NT_STATUS_NO_MEMORY;
160         }
161
162         DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
163
164         if (lm_pwd)
165                 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
166         if (nt_pwd)
167                 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
168         if (lm_interactive_pwd)
169                 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
170         if (nt_interactive_pwd)
171                 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
172
173         if (plaintext)
174                 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
175
176         (*user_info)->encrypted = encrypted;
177
178         (*user_info)->logon_parameters = 0;
179
180         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
181
182         return NT_STATUS_OK;
183 }
184
185 /****************************************************************************
186  Create an auth_usersupplied_data structure after appropriate mapping.
187 ****************************************************************************/
188
189 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, 
190                             const char *smb_name, 
191                             const char *client_domain, 
192                             const char *wksta_name, 
193                             DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
194                             DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
195                             DATA_BLOB *plaintext, 
196                             bool encrypted)
197 {
198         const char *domain;
199         NTSTATUS result;
200         bool was_mapped;
201         fstring internal_username;
202         fstrcpy(internal_username, smb_name);
203         was_mapped = map_username(internal_username); 
204         
205         DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
206               client_domain, smb_name, wksta_name));
207         
208         /* don't allow "" as a domain, fixes a Win9X bug 
209            where it doens't supply a domain for logon script
210            'net use' commands.                                 */
211
212         if ( *client_domain )
213                 domain = client_domain;
214         else
215                 domain = lp_workgroup();
216
217         /* do what win2k does.  Always map unknown domains to our own
218            and let the "passdb backend" handle unknown users. */
219
220         if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) ) 
221                 domain = my_sam_name();
222         
223         /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
224         
225         result = make_user_info(user_info, smb_name, internal_username, 
226                               client_domain, domain, wksta_name, 
227                               lm_pwd, nt_pwd,
228                               lm_interactive_pwd, nt_interactive_pwd,
229                               plaintext, encrypted);
230         if (NT_STATUS_IS_OK(result)) {
231                 (*user_info)->was_mapped = was_mapped;
232         }
233         return result;
234 }
235
236 /****************************************************************************
237  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
238  Decrypt and encrypt the passwords.
239 ****************************************************************************/
240
241 bool make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
242                                      const char *smb_name, 
243                                      const char *client_domain, 
244                                      const char *wksta_name, 
245                                      uint32 logon_parameters,
246                                      const uchar *lm_network_pwd,
247                                      int lm_pwd_len,
248                                      const uchar *nt_network_pwd,
249                                      int nt_pwd_len)
250 {
251         bool ret;
252         NTSTATUS status;
253         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
254         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
255
256         status = make_user_info_map(user_info,
257                                     smb_name, client_domain, 
258                                     wksta_name, 
259                                     lm_pwd_len ? &lm_blob : NULL, 
260                                     nt_pwd_len ? &nt_blob : NULL,
261                                     NULL, NULL, NULL,
262                                     True);
263
264         if (NT_STATUS_IS_OK(status)) {
265                 (*user_info)->logon_parameters = logon_parameters;
266         }
267         ret = NT_STATUS_IS_OK(status) ? True : False;
268
269         data_blob_free(&lm_blob);
270         data_blob_free(&nt_blob);
271         return ret;
272 }
273
274 /****************************************************************************
275  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
276  Decrypt and encrypt the passwords.
277 ****************************************************************************/
278
279 bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
280                                          const char *smb_name, 
281                                          const char *client_domain, 
282                                          const char *wksta_name, 
283                                          uint32 logon_parameters,
284                                          const uchar chal[8], 
285                                          const uchar lm_interactive_pwd[16], 
286                                          const uchar nt_interactive_pwd[16], 
287                                          const uchar *dc_sess_key)
288 {
289         unsigned char lm_pwd[16];
290         unsigned char nt_pwd[16];
291         unsigned char local_lm_response[24];
292         unsigned char local_nt_response[24];
293         unsigned char key[16];
294         
295         ZERO_STRUCT(key);
296         memcpy(key, dc_sess_key, 8);
297         
298         if (lm_interactive_pwd)
299                 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
300
301         if (nt_interactive_pwd)
302                 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
303         
304 #ifdef DEBUG_PASSWORD
305         DEBUG(100,("key:"));
306         dump_data(100, key, sizeof(key));
307         
308         DEBUG(100,("lm owf password:"));
309         dump_data(100, lm_pwd, sizeof(lm_pwd));
310         
311         DEBUG(100,("nt owf password:"));
312         dump_data(100, nt_pwd, sizeof(nt_pwd));
313 #endif
314         
315         if (lm_interactive_pwd)
316                 SamOEMhash(lm_pwd, key, sizeof(lm_pwd));
317         
318         if (nt_interactive_pwd)
319                 SamOEMhash(nt_pwd, key, sizeof(nt_pwd));
320         
321 #ifdef DEBUG_PASSWORD
322         DEBUG(100,("decrypt of lm owf password:"));
323         dump_data(100, lm_pwd, sizeof(lm_pwd));
324         
325         DEBUG(100,("decrypt of nt owf password:"));
326         dump_data(100, nt_pwd, sizeof(nt_pwd));
327 #endif
328         
329         if (lm_interactive_pwd)
330                 SMBOWFencrypt(lm_pwd, chal,
331                               local_lm_response);
332
333         if (nt_interactive_pwd)
334                 SMBOWFencrypt(nt_pwd, chal,
335                               local_nt_response);
336         
337         /* Password info paranoia */
338         ZERO_STRUCT(key);
339
340         {
341                 bool ret;
342                 NTSTATUS nt_status;
343                 DATA_BLOB local_lm_blob;
344                 DATA_BLOB local_nt_blob;
345
346                 DATA_BLOB lm_interactive_blob;
347                 DATA_BLOB nt_interactive_blob;
348                 
349                 if (lm_interactive_pwd) {
350                         local_lm_blob = data_blob(local_lm_response,
351                                                   sizeof(local_lm_response));
352                         lm_interactive_blob = data_blob(lm_pwd,
353                                                         sizeof(lm_pwd));
354                         ZERO_STRUCT(lm_pwd);
355                 }
356                 
357                 if (nt_interactive_pwd) {
358                         local_nt_blob = data_blob(local_nt_response,
359                                                   sizeof(local_nt_response));
360                         nt_interactive_blob = data_blob(nt_pwd,
361                                                         sizeof(nt_pwd));
362                         ZERO_STRUCT(nt_pwd);
363                 }
364
365                 nt_status = make_user_info_map(
366                         user_info, 
367                         smb_name, client_domain, wksta_name, 
368                         lm_interactive_pwd ? &local_lm_blob : NULL,
369                         nt_interactive_pwd ? &local_nt_blob : NULL,
370                         lm_interactive_pwd ? &lm_interactive_blob : NULL,
371                         nt_interactive_pwd ? &nt_interactive_blob : NULL,
372                         NULL, True);
373
374                 if (NT_STATUS_IS_OK(nt_status)) {
375                         (*user_info)->logon_parameters = logon_parameters;
376                 }
377
378                 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
379                 data_blob_free(&local_lm_blob);
380                 data_blob_free(&local_nt_blob);
381                 data_blob_free(&lm_interactive_blob);
382                 data_blob_free(&nt_interactive_blob);
383                 return ret;
384         }
385 }
386
387
388 /****************************************************************************
389  Create an auth_usersupplied_data structure
390 ****************************************************************************/
391
392 bool make_user_info_for_reply(auth_usersupplied_info **user_info, 
393                               const char *smb_name, 
394                               const char *client_domain,
395                               const uint8 chal[8],
396                               DATA_BLOB plaintext_password)
397 {
398
399         DATA_BLOB local_lm_blob;
400         DATA_BLOB local_nt_blob;
401         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
402                         
403         /*
404          * Not encrypted - do so.
405          */
406         
407         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
408                  "format.\n"));
409         
410         if (plaintext_password.data) {
411                 unsigned char local_lm_response[24];
412                 
413 #ifdef DEBUG_PASSWORD
414                 DEBUG(10,("Unencrypted password (len %d):\n",
415                           (int)plaintext_password.length));
416                 dump_data(100, plaintext_password.data,
417                           plaintext_password.length);
418 #endif
419
420                 SMBencrypt( (const char *)plaintext_password.data,
421                             (const uchar*)chal, local_lm_response);
422                 local_lm_blob = data_blob(local_lm_response, 24);
423                 
424                 /* We can't do an NT hash here, as the password needs to be
425                    case insensitive */
426                 local_nt_blob = data_blob_null; 
427                 
428         } else {
429                 local_lm_blob = data_blob_null; 
430                 local_nt_blob = data_blob_null; 
431         }
432         
433         ret = make_user_info_map(
434                 user_info, smb_name, client_domain, 
435                 get_remote_machine_name(),
436                 local_lm_blob.data ? &local_lm_blob : NULL,
437                 local_nt_blob.data ? &local_nt_blob : NULL,
438                 NULL, NULL,
439                 plaintext_password.data ? &plaintext_password : NULL, 
440                 False);
441         
442         data_blob_free(&local_lm_blob);
443         return NT_STATUS_IS_OK(ret) ? True : False;
444 }
445
446 /****************************************************************************
447  Create an auth_usersupplied_data structure
448 ****************************************************************************/
449
450 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
451                                       const char *smb_name,
452                                       const char *client_domain, 
453                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
454 {
455         return make_user_info_map(user_info, smb_name, 
456                                   client_domain, 
457                                   get_remote_machine_name(), 
458                                   lm_resp.data ? &lm_resp : NULL, 
459                                   nt_resp.data ? &nt_resp : NULL, 
460                                   NULL, NULL, NULL,
461                                   True);
462 }
463
464 /****************************************************************************
465  Create a guest user_info blob, for anonymous authenticaion.
466 ****************************************************************************/
467
468 bool make_user_info_guest(auth_usersupplied_info **user_info) 
469 {
470         NTSTATUS nt_status;
471
472         nt_status = make_user_info(user_info, 
473                                    "","", 
474                                    "","", 
475                                    "", 
476                                    NULL, NULL, 
477                                    NULL, NULL, 
478                                    NULL,
479                                    True);
480                               
481         return NT_STATUS_IS_OK(nt_status) ? True : False;
482 }
483
484 static int server_info_dtor(auth_serversupplied_info *server_info)
485 {
486         TALLOC_FREE(server_info->sam_account);
487         ZERO_STRUCTP(server_info);
488         return 0;
489 }
490
491 /***************************************************************************
492  Make a server_info struct. Free with TALLOC_FREE().
493 ***************************************************************************/
494
495 static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
496 {
497         struct auth_serversupplied_info *result;
498
499         result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
500         if (result == NULL) {
501                 DEBUG(0, ("talloc failed\n"));
502                 return NULL;
503         }
504
505         talloc_set_destructor(result, server_info_dtor);
506
507         /* Initialise the uid and gid values to something non-zero
508            which may save us from giving away root access if there
509            is a bug in allocating these fields. */
510
511         result->utok.uid = -1;
512         result->utok.gid = -1;
513         return result;
514 }
515
516 static char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
517 {
518         fstring tmp;
519
520         alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
521         return talloc_strdup(mem_ctx, tmp);
522 }
523
524 /***************************************************************************
525  Is the incoming username our own machine account ?
526  If so, the connection is almost certainly from winbindd.
527 ***************************************************************************/
528
529 static bool is_our_machine_account(const char *username)
530 {
531         bool ret;
532         char *truncname = NULL;
533         size_t ulen = strlen(username);
534
535         if (ulen == 0 || username[ulen-1] != '$') {
536                 return false;
537         }
538         truncname = SMB_STRDUP(username);
539         if (!truncname) {
540                 return false;
541         }
542         truncname[ulen-1] = '\0';
543         ret = strequal(truncname, global_myname());
544         SAFE_FREE(truncname);
545         return ret;
546 }
547
548 /***************************************************************************
549  Make (and fill) a user_info struct from a struct samu
550 ***************************************************************************/
551
552 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
553                               struct samu *sampass)
554 {
555         struct passwd *pwd;
556         gid_t *gids;
557         auth_serversupplied_info *result;
558         int i;
559         size_t num_gids;
560         DOM_SID unix_group_sid;
561         const char *username = pdb_get_username(sampass);
562         NTSTATUS status;
563
564         if ( !(result = make_server_info(NULL)) ) {
565                 return NT_STATUS_NO_MEMORY;
566         }
567
568         if ( !(pwd = getpwnam_alloc(result, username)) ) {
569                 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
570                           pdb_get_username(sampass)));
571                 TALLOC_FREE(result);
572                 return NT_STATUS_NO_SUCH_USER;
573         }
574
575         result->sam_account = sampass;
576         /* Ensure thaat the sampass will be freed with the result */
577         talloc_steal(result, sampass);
578         result->unix_name = pwd->pw_name;
579         /* Ensure that we keep pwd->pw_name, because we will free pwd below */
580         talloc_steal(result, pwd->pw_name);
581         result->utok.gid = pwd->pw_gid;
582         result->utok.uid = pwd->pw_uid;
583
584         TALLOC_FREE(pwd);
585
586         result->sanitized_username = sanitize_username(result,
587                                                        result->unix_name);
588         if (result->sanitized_username == NULL) {
589                 TALLOC_FREE(result);
590                 return NT_STATUS_NO_MEMORY;
591         }
592
593         if (IS_DC && is_our_machine_account(username)) {
594                 /*
595                  * Ensure for a connection from our own
596                  * machine account (from winbindd on a DC)
597                  * there are no supplementary groups.
598                  * Prevents loops in calling gid_to_sid().
599                  */
600                 result->sids = NULL;
601                 gids = NULL;
602                 result->num_sids = 0;
603
604                 /*
605                  * This is a hack of monstrous proportions.
606                  * If we know it's winbindd talking to us,
607                  * we know we must never recurse into it,
608                  * so turn off contacting winbindd for this
609                  * entire process. This will get fixed when
610                  * winbindd doesn't need to talk to smbd on
611                  * a PDC. JRA.
612                  */
613
614                 (void)winbind_off();
615
616                 DEBUG(10, ("make_server_info_sam: our machine account %s "
617                         "setting supplementary group list empty and "
618                         "turning off winbindd requests.\n",
619                         username));
620         } else {
621                 status = pdb_enum_group_memberships(result, sampass,
622                                             &result->sids, &gids,
623                                             &result->num_sids);
624
625                 if (!NT_STATUS_IS_OK(status)) {
626                         DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
627                                    nt_errstr(status)));
628                         result->sam_account = NULL; /* Don't free on error exit. */
629                         TALLOC_FREE(result);
630                         return status;
631                 }
632         }
633
634         /* Add the "Unix Group" SID for each gid to catch mapped groups
635            and their Unix equivalent.  This is to solve the backwards 
636            compatibility problem of 'valid users = +ntadmin' where 
637            ntadmin has been paired with "Domain Admins" in the group 
638            mapping table.  Otherwise smb.conf would need to be changed
639            to 'valid user = "Domain Admins"'.  --jerry */
640         
641         num_gids = result->num_sids;
642         for ( i=0; i<num_gids; i++ ) {
643                 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
644                         DEBUG(1,("make_server_info_sam: Failed to create SID "
645                                 "for gid %d!\n", gids[i]));
646                         continue;
647                 }
648                 status = add_sid_to_array_unique(result, &unix_group_sid,
649                                                  &result->sids,
650                                                  &result->num_sids);
651                 if (!NT_STATUS_IS_OK(status)) {
652                         result->sam_account = NULL; /* Don't free on error exit. */
653                         TALLOC_FREE(result);
654                         return status;
655                 }
656         }
657
658         /* For now we throw away the gids and convert via sid_to_gid
659          * later. This needs fixing, but I'd like to get the code straight and
660          * simple first. */
661          
662         TALLOC_FREE(gids);
663
664         DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
665                  pdb_get_username(sampass), result->unix_name));
666
667         *server_info = result;
668
669         return NT_STATUS_OK;
670 }
671
672 static NTSTATUS log_nt_token(NT_USER_TOKEN *token)
673 {
674         TALLOC_CTX *frame = talloc_stackframe();
675         char *command;
676         char *group_sidstr;
677         size_t i;
678
679         if ((lp_log_nt_token_command() == NULL) ||
680             (strlen(lp_log_nt_token_command()) == 0)) {
681                 TALLOC_FREE(frame);
682                 return NT_STATUS_OK;
683         }
684
685         group_sidstr = talloc_strdup(frame, "");
686         for (i=1; i<token->num_sids; i++) {
687                 group_sidstr = talloc_asprintf(
688                         frame, "%s %s", group_sidstr,
689                         sid_string_talloc(frame, &token->user_sids[i]));
690         }
691
692         command = talloc_string_sub(
693                 frame, lp_log_nt_token_command(),
694                 "%s", sid_string_talloc(frame, &token->user_sids[0]));
695         command = talloc_string_sub(frame, command, "%t", group_sidstr);
696
697         if (command == NULL) {
698                 TALLOC_FREE(frame);
699                 return NT_STATUS_NO_MEMORY;
700         }
701
702         DEBUG(8, ("running command: [%s]\n", command));
703         if (smbrun(command, NULL) != 0) {
704                 DEBUG(0, ("Could not log NT token\n"));
705                 TALLOC_FREE(frame);
706                 return NT_STATUS_ACCESS_DENIED;
707         }
708
709         TALLOC_FREE(frame);
710         return NT_STATUS_OK;
711 }
712
713 /*
714  * Create the token to use from server_info->sam_account and
715  * server_info->sids (the info3/sam groups). Find the unix gids.
716  */
717
718 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
719 {
720         NTSTATUS status;
721         size_t i;
722
723         /*
724          * If winbind is not around, we can not make much use of the SIDs the
725          * domain controller provided us with. Likewise if the user name was
726          * mapped to some local unix user.
727          */
728
729         if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
730             (server_info->nss_token)) {
731                 status = create_token_from_username(server_info,
732                                                     server_info->unix_name,
733                                                     server_info->guest,
734                                                     &server_info->utok.uid,
735                                                     &server_info->utok.gid,
736                                                     &server_info->unix_name,
737                                                     &server_info->ptok);
738
739         } else {
740                 server_info->ptok = create_local_nt_token(
741                         server_info,
742                         pdb_get_user_sid(server_info->sam_account),
743                         server_info->guest,
744                         server_info->num_sids, server_info->sids);
745                 status = server_info->ptok ?
746                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
747         }
748
749         if (!NT_STATUS_IS_OK(status)) {
750                 return status;
751         }
752
753         /* Convert the SIDs to gids. */
754
755         server_info->utok.ngroups = 0;
756         server_info->utok.groups = NULL;
757
758         /* Start at index 1, where the groups start. */
759
760         for (i=1; i<server_info->ptok->num_sids; i++) {
761                 gid_t gid;
762                 DOM_SID *sid = &server_info->ptok->user_sids[i];
763
764                 if (!sid_to_gid(sid, &gid)) {
765                         DEBUG(10, ("Could not convert SID %s to gid, "
766                                    "ignoring it\n", sid_string_dbg(sid)));
767                         continue;
768                 }
769                 add_gid_to_array_unique(server_info, gid,
770                                         &server_info->utok.groups,
771                                         &server_info->utok.ngroups);
772         }
773
774         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
775
776         status = log_nt_token(server_info->ptok);
777         return status;
778 }
779
780 /*
781  * Create an artificial NT token given just a username. (Initially indended
782  * for force user)
783  *
784  * We go through lookup_name() to avoid problems we had with 'winbind use
785  * default domain'.
786  *
787  * We have 3 cases:
788  *
789  * unmapped unix users: Go directly to nss to find the user's group.
790  *
791  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
792  *
793  * If the user is provided by winbind, the primary gid is set to "domain
794  * users" of the user's domain. For an explanation why this is necessary, see
795  * the thread starting at
796  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
797  */
798
799 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
800                                     bool is_guest,
801                                     uid_t *uid, gid_t *gid,
802                                     char **found_username,
803                                     struct nt_user_token **token)
804 {
805         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
806         TALLOC_CTX *tmp_ctx;
807         DOM_SID user_sid;
808         enum lsa_SidType type;
809         gid_t *gids;
810         DOM_SID *group_sids;
811         DOM_SID unix_group_sid;
812         size_t num_group_sids;
813         size_t num_gids;
814         size_t i;
815
816         tmp_ctx = talloc_new(NULL);
817         if (tmp_ctx == NULL) {
818                 DEBUG(0, ("talloc_new failed\n"));
819                 return NT_STATUS_NO_MEMORY;
820         }
821
822         if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
823                          NULL, NULL, &user_sid, &type)) {
824                 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
825                 goto done;
826         }
827
828         if (type != SID_NAME_USER) {
829                 DEBUG(1, ("%s is a %s, not a user\n", username,
830                           sid_type_lookup(type)));
831                 goto done;
832         }
833
834         if (!sid_to_uid(&user_sid, uid)) {
835                 DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
836                           username, sid_string_dbg(&user_sid)));
837                 goto done;
838         }
839
840         if (sid_check_is_in_our_domain(&user_sid)) {
841                 bool ret;
842
843                 /* This is a passdb user, so ask passdb */
844
845                 struct samu *sam_acct = NULL;
846
847                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
848                         result = NT_STATUS_NO_MEMORY;
849                         goto done;
850                 }
851
852                 become_root();
853                 ret = pdb_getsampwsid(sam_acct, &user_sid);
854                 unbecome_root();
855
856                 if (!ret) {
857                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
858                                   sid_string_dbg(&user_sid), username));
859                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
860                         goto unix_user;
861                 }
862
863                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
864                                                     &group_sids, &gids,
865                                                     &num_group_sids);
866                 if (!NT_STATUS_IS_OK(result)) {
867                         DEBUG(10, ("enum_group_memberships failed for %s\n",
868                                    username));
869                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
870                         goto unix_user;
871                 }
872
873                 /* see the smb_panic() in pdb_default_enum_group_memberships */
874                 SMB_ASSERT(num_group_sids > 0); 
875
876                 *gid = gids[0];
877
878                 /* Ensure we're returning the found_username on the right context. */
879                 *found_username = talloc_strdup(mem_ctx,
880                                                 pdb_get_username(sam_acct));
881
882         } else  if (sid_check_is_in_unix_users(&user_sid)) {
883
884                 /* This is a unix user not in passdb. We need to ask nss
885                  * directly, without consulting passdb */
886
887                 struct passwd *pass;
888
889                 /*
890                  * This goto target is used as a fallback for the passdb
891                  * case. The concrete bug report is when passdb gave us an
892                  * unmapped gid.
893                  */
894
895         unix_user:
896
897                 uid_to_unix_users_sid(*uid, &user_sid);
898
899                 pass = getpwuid_alloc(tmp_ctx, *uid);
900                 if (pass == NULL) {
901                         DEBUG(1, ("getpwuid(%d) for user %s failed\n",
902                                   *uid, username));
903                         goto done;
904                 }
905
906                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
907                                          &gids, &num_group_sids)) {
908                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
909                                   username));
910                         goto done;
911                 }
912
913                 if (num_group_sids) {
914                         group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
915                         if (group_sids == NULL) {
916                                 DEBUG(1, ("TALLOC_ARRAY failed\n"));
917                                 result = NT_STATUS_NO_MEMORY;
918                                 goto done;
919                         }
920                 } else {
921                         group_sids = NULL;
922                 }
923
924                 for (i=0; i<num_group_sids; i++) {
925                         gid_to_sid(&group_sids[i], gids[i]);
926                 }
927
928                 /* In getgroups_unix_user we always set the primary gid */
929                 SMB_ASSERT(num_group_sids > 0); 
930
931                 *gid = gids[0];
932
933                 /* Ensure we're returning the found_username on the right context. */
934                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
935         } else {
936
937                 /* This user is from winbind, force the primary gid to the
938                  * user's "domain users" group. Under certain circumstances
939                  * (user comes from NT4), this might be a loss of
940                  * information. But we can not rely on winbind getting the
941                  * correct info. AD might prohibit winbind looking up that
942                  * information. */
943
944                 uint32 dummy;
945
946                 num_group_sids = 1;
947                 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
948                 if (group_sids == NULL) {
949                         DEBUG(1, ("TALLOC_ARRAY failed\n"));
950                         result = NT_STATUS_NO_MEMORY;
951                         goto done;
952                 }
953
954                 sid_copy(&group_sids[0], &user_sid);
955                 sid_split_rid(&group_sids[0], &dummy);
956                 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
957
958                 if (!sid_to_gid(&group_sids[0], gid)) {
959                         DEBUG(1, ("sid_to_gid(%s) failed\n",
960                                   sid_string_dbg(&group_sids[0])));
961                         goto done;
962                 }
963
964                 gids = gid;
965
966                 /* Ensure we're returning the found_username on the right context. */
967                 *found_username = talloc_strdup(mem_ctx, username);
968         }
969
970         /* Add the "Unix Group" SID for each gid to catch mapped groups
971            and their Unix equivalent.  This is to solve the backwards
972            compatibility problem of 'valid users = +ntadmin' where
973            ntadmin has been paired with "Domain Admins" in the group
974            mapping table.  Otherwise smb.conf would need to be changed
975            to 'valid user = "Domain Admins"'.  --jerry */
976
977         num_gids = num_group_sids;
978         for ( i=0; i<num_gids; i++ ) {
979                 gid_t high, low;
980
981                 /* don't pickup anything managed by Winbind */
982
983                 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
984                         continue;
985
986                 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
987                         DEBUG(1,("create_token_from_username: Failed to create SID "
988                                 "for gid %d!\n", gids[i]));
989                         continue;
990                 }
991                 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
992                                                  &group_sids, &num_group_sids);
993                 if (!NT_STATUS_IS_OK(result)) {
994                         goto done;
995                 }
996         }
997
998         /* Ensure we're creating the nt_token on the right context. */
999         *token = create_local_nt_token(mem_ctx, &user_sid,
1000                                        is_guest, num_group_sids, group_sids);
1001
1002         if ((*token == NULL) || (*found_username == NULL)) {
1003                 result = NT_STATUS_NO_MEMORY;
1004                 goto done;
1005         }
1006
1007         result = NT_STATUS_OK;
1008  done:
1009         TALLOC_FREE(tmp_ctx);
1010         return result;
1011 }
1012
1013 /***************************************************************************
1014  Build upon create_token_from_username:
1015
1016  Expensive helper function to figure out whether a user given its name is
1017  member of a particular group.
1018 ***************************************************************************/
1019
1020 bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
1021 {
1022         NTSTATUS status;
1023         uid_t uid;
1024         gid_t gid;
1025         char *found_username;
1026         struct nt_user_token *token;
1027         bool result;
1028
1029         TALLOC_CTX *mem_ctx;
1030
1031         mem_ctx = talloc_new(NULL);
1032         if (mem_ctx == NULL) {
1033                 DEBUG(0, ("talloc_new failed\n"));
1034                 return False;
1035         }
1036
1037         status = create_token_from_username(mem_ctx, username, False,
1038                                             &uid, &gid, &found_username,
1039                                             &token);
1040
1041         if (!NT_STATUS_IS_OK(status)) {
1042                 DEBUG(10, ("could not create token for %s\n", username));
1043                 return False;
1044         }
1045
1046         result = nt_token_check_sid(group_sid, token);
1047
1048         TALLOC_FREE(mem_ctx);
1049         return result;
1050         
1051 }
1052
1053 bool user_in_group(const char *username, const char *groupname)
1054 {
1055         TALLOC_CTX *mem_ctx;
1056         DOM_SID group_sid;
1057         bool ret;
1058
1059         mem_ctx = talloc_new(NULL);
1060         if (mem_ctx == NULL) {
1061                 DEBUG(0, ("talloc_new failed\n"));
1062                 return False;
1063         }
1064
1065         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1066                           NULL, NULL, &group_sid, NULL);
1067         TALLOC_FREE(mem_ctx);
1068
1069         if (!ret) {
1070                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1071                 return False;
1072         }
1073
1074         return user_in_group_sid(username, &group_sid);
1075 }
1076
1077 /***************************************************************************
1078  Make (and fill) a server_info struct from a 'struct passwd' by conversion
1079  to a struct samu
1080 ***************************************************************************/
1081
1082 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
1083                              char *unix_username,
1084                              struct passwd *pwd)
1085 {
1086         NTSTATUS status;
1087         struct samu *sampass = NULL;
1088         gid_t *gids;
1089         TALLOC_CTX *mem_ctx = NULL;
1090         DOM_SID u_sid;
1091         enum lsa_SidType type;
1092         auth_serversupplied_info *result;
1093         
1094         if ( !(sampass = samu_new( NULL )) ) {
1095                 return NT_STATUS_NO_MEMORY;
1096         }
1097         
1098         status = samu_set_unix( sampass, pwd );
1099         if (!NT_STATUS_IS_OK(status)) {
1100                 return status;
1101         }
1102
1103         result = make_server_info(NULL);
1104         if (result == NULL) {
1105                 TALLOC_FREE(sampass);
1106                 return NT_STATUS_NO_MEMORY;
1107         }
1108
1109         result->sam_account = sampass;
1110
1111         result->unix_name = talloc_strdup(result, unix_username);
1112         result->sanitized_username = sanitize_username(result, unix_username);
1113
1114         if ((result->unix_name == NULL)
1115             || (result->sanitized_username == NULL)) {
1116                 TALLOC_FREE(sampass);
1117                 TALLOC_FREE(result);
1118                 return NT_STATUS_NO_MEMORY;
1119         }
1120
1121         result->utok.uid = pwd->pw_uid;
1122         result->utok.gid = pwd->pw_gid;
1123
1124         status = pdb_enum_group_memberships(result, sampass,
1125                                             &result->sids, &gids,
1126                                             &result->num_sids);
1127
1128         if (!NT_STATUS_IS_OK(status)) {
1129                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1130                            nt_errstr(status)));
1131                 TALLOC_FREE(result);
1132                 return status;
1133         }
1134
1135         /*
1136          * The SID returned in server_info->sam_account is based
1137          * on our SAM sid even though for a pure UNIX account this should
1138          * not be the case as it doesn't really exist in the SAM db.
1139          * This causes lookups on "[in]valid users" to fail as they
1140          * will lookup this name as a "Unix User" SID to check against
1141          * the user token. Fix this by adding the "Unix User"\unix_username
1142          * SID to the sid array. The correct fix should probably be
1143          * changing the server_info->sam_account user SID to be a
1144          * S-1-22 Unix SID, but this might break old configs where
1145          * plaintext passwords were used with no SAM backend.
1146          */
1147
1148         mem_ctx = talloc_init("make_server_info_pw_tmp");
1149         if (!mem_ctx) {
1150                 TALLOC_FREE(result);
1151                 return NT_STATUS_NO_MEMORY;
1152         }
1153
1154         if (!lookup_domain_name(mem_ctx,
1155                                 unix_users_domain_name(), unix_username,
1156                                 LOOKUP_NAME_ALL,
1157                                 NULL, NULL, &u_sid, &type)) {
1158                 TALLOC_FREE(result);
1159                 TALLOC_FREE(mem_ctx);
1160                 return NT_STATUS_NO_SUCH_USER;
1161         }
1162
1163         TALLOC_FREE(mem_ctx);
1164
1165         if (type != SID_NAME_USER) {
1166                 TALLOC_FREE(result);
1167                 return NT_STATUS_NO_SUCH_USER;
1168         }
1169
1170         status = add_sid_to_array_unique(result, &u_sid,
1171                                          &result->sids,
1172                                          &result->num_sids);
1173         if (!NT_STATUS_IS_OK(status)) {
1174                 TALLOC_FREE(result);
1175                 return status;
1176         }
1177
1178         /* For now we throw away the gids and convert via sid_to_gid
1179          * later. This needs fixing, but I'd like to get the code straight and
1180          * simple first. */
1181         TALLOC_FREE(gids);
1182
1183         *server_info = result;
1184
1185         return NT_STATUS_OK;
1186 }
1187
1188 /***************************************************************************
1189  Make (and fill) a user_info struct for a guest login.
1190  This *must* succeed for smbd to start. If there is no mapping entry for
1191  the guest gid, then create one.
1192 ***************************************************************************/
1193
1194 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1195 {
1196         NTSTATUS status;
1197         struct samu *sampass = NULL;
1198         DOM_SID guest_sid;
1199         bool ret;
1200         char zeros[16];
1201         fstring tmp;
1202
1203         if ( !(sampass = samu_new( NULL )) ) {
1204                 return NT_STATUS_NO_MEMORY;
1205         }
1206
1207         sid_copy(&guest_sid, get_global_sam_sid());
1208         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1209
1210         become_root();
1211         ret = pdb_getsampwsid(sampass, &guest_sid);
1212         unbecome_root();
1213
1214         if (!ret) {
1215                 TALLOC_FREE(sampass);
1216                 return NT_STATUS_NO_SUCH_USER;
1217         }
1218
1219         status = make_server_info_sam(server_info, sampass);
1220         if (!NT_STATUS_IS_OK(status)) {
1221                 TALLOC_FREE(sampass);
1222                 return status;
1223         }
1224         
1225         (*server_info)->guest = True;
1226
1227         status = create_local_token(*server_info);
1228         if (!NT_STATUS_IS_OK(status)) {
1229                 DEBUG(10, ("create_local_token failed: %s\n",
1230                            nt_errstr(status)));
1231                 return status;
1232         }
1233
1234         /* annoying, but the Guest really does have a session key, and it is
1235            all zeros! */
1236         ZERO_STRUCT(zeros);
1237         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1238         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1239
1240         alpha_strcpy(tmp, pdb_get_username(sampass), ". _-$", sizeof(tmp));
1241         (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp);
1242
1243         return NT_STATUS_OK;
1244 }
1245
1246 /****************************************************************************
1247   Fake a auth_serversupplied_info just from a username
1248 ****************************************************************************/
1249
1250 NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
1251                                        const char *username,
1252                                        bool is_guest,
1253                                        struct auth_serversupplied_info **presult)
1254 {
1255         struct auth_serversupplied_info *result;
1256         struct passwd *pwd;
1257         NTSTATUS status;
1258
1259         pwd = getpwnam_alloc(talloc_tos(), username);
1260         if (pwd == NULL) {
1261                 return NT_STATUS_NO_SUCH_USER;
1262         }
1263
1264         status = make_server_info_pw(&result, pwd->pw_name, pwd);
1265
1266         TALLOC_FREE(pwd);
1267
1268         if (!NT_STATUS_IS_OK(status)) {
1269                 return status;
1270         }
1271
1272         result->nss_token = true;
1273         result->guest = is_guest;
1274
1275         status = create_local_token(result);
1276
1277         if (!NT_STATUS_IS_OK(status)) {
1278                 TALLOC_FREE(result);
1279                 return status;
1280         }
1281
1282         *presult = result;
1283         return NT_STATUS_OK;
1284 }
1285
1286
1287 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
1288                                                  auth_serversupplied_info *src)
1289 {
1290         auth_serversupplied_info *dst;
1291
1292         dst = make_server_info(mem_ctx);
1293         if (dst == NULL) {
1294                 return NULL;
1295         }
1296
1297         dst->guest = src->guest;
1298         dst->utok.uid = src->utok.uid;
1299         dst->utok.gid = src->utok.gid;
1300         dst->utok.ngroups = src->utok.ngroups;
1301         if (src->utok.ngroups != 0) {
1302                 dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
1303                         dst, src->utok.groups,
1304                         sizeof(gid_t)*dst->utok.ngroups);
1305         } else {
1306                 dst->utok.groups = NULL;
1307         }
1308
1309         if (src->ptok) {
1310                 dst->ptok = dup_nt_token(dst, src->ptok);
1311                 if (!dst->ptok) {
1312                         TALLOC_FREE(dst);
1313                         return NULL;
1314                 }
1315         }
1316         
1317         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1318                                                 src->user_session_key.length);
1319
1320         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1321                                                 src->lm_session_key.length);
1322
1323         dst->sam_account = samu_new(NULL);
1324         if (!dst->sam_account) {
1325                 TALLOC_FREE(dst);
1326                 return NULL;
1327         }
1328
1329         if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1330                 TALLOC_FREE(dst);
1331                 return NULL;
1332         }
1333         
1334         dst->pam_handle = NULL;
1335         dst->unix_name = talloc_strdup(dst, src->unix_name);
1336         if (!dst->unix_name) {
1337                 TALLOC_FREE(dst);
1338                 return NULL;
1339         }
1340
1341         dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
1342         if (!dst->sanitized_username) {
1343                 TALLOC_FREE(dst);
1344                 return NULL;
1345         }
1346
1347         return dst;
1348 }
1349
1350 /*
1351  * Set a new session key. Used in the rpc server where we have to override the
1352  * SMB level session key with SystemLibraryDTC
1353  */
1354
1355 bool server_info_set_session_key(struct auth_serversupplied_info *info,
1356                                  DATA_BLOB session_key)
1357 {
1358         TALLOC_FREE(info->user_session_key.data);
1359
1360         info->user_session_key = data_blob_talloc(
1361                 info, session_key.data, session_key.length);
1362
1363         return (info->user_session_key.data != NULL);
1364 }
1365
1366 static auth_serversupplied_info *guest_info = NULL;
1367
1368 bool init_guest_info(void)
1369 {
1370         if (guest_info != NULL)
1371                 return True;
1372
1373         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1374 }
1375
1376 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1377                                 auth_serversupplied_info **server_info)
1378 {
1379         *server_info = copy_serverinfo(mem_ctx, guest_info);
1380         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1381 }
1382
1383 bool copy_current_user(struct current_user *dst, struct current_user *src)
1384 {
1385         gid_t *groups;
1386         NT_USER_TOKEN *nt_token;
1387
1388         groups = (gid_t *)memdup(src->ut.groups,
1389                                  sizeof(gid_t) * src->ut.ngroups);
1390         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1391                 return False;
1392         }
1393
1394         nt_token = dup_nt_token(NULL, src->nt_user_token);
1395         if (nt_token == NULL) {
1396                 SAFE_FREE(groups);
1397                 return False;
1398         }
1399
1400         dst->conn = src->conn;
1401         dst->vuid = src->vuid;
1402         dst->ut.uid = src->ut.uid;
1403         dst->ut.gid = src->ut.gid;
1404         dst->ut.ngroups = src->ut.ngroups;
1405         dst->ut.groups = groups;
1406         dst->nt_user_token = nt_token;
1407         return True;
1408 }
1409
1410 /***************************************************************************
1411  Purely internal function for make_server_info_info3
1412  Fill the sam account from getpwnam
1413 ***************************************************************************/
1414 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1415                                  const char *domain,
1416                                  const char *username,
1417                                  char **found_username,
1418                                  uid_t *uid, gid_t *gid,
1419                                  struct samu *account,
1420                                  bool *username_was_mapped)
1421 {
1422         NTSTATUS nt_status;
1423         fstring dom_user, lower_username;
1424         fstring real_username;
1425         struct passwd *passwd;
1426
1427         fstrcpy( lower_username, username );
1428         strlower_m( lower_username );
1429
1430         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1431                 lower_username);
1432
1433         /* Get the passwd struct.  Try to create the account is necessary. */
1434
1435         *username_was_mapped = map_username( dom_user );
1436
1437         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1438                 return NT_STATUS_NO_SUCH_USER;
1439
1440         *uid = passwd->pw_uid;
1441         *gid = passwd->pw_gid;
1442
1443         /* This is pointless -- there is no suport for differing 
1444            unix and windows names.  Make sure to always store the 
1445            one we actually looked up and succeeded. Have I mentioned
1446            why I hate the 'winbind use default domain' parameter?   
1447                                          --jerry              */
1448            
1449         *found_username = talloc_strdup( mem_ctx, real_username );
1450         
1451         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1452
1453         nt_status = samu_set_unix( account, passwd );
1454         
1455         TALLOC_FREE(passwd);
1456         
1457         return nt_status;
1458 }
1459
1460 /****************************************************************************
1461  Wrapper to allow the getpwnam() call to strip the domain name and 
1462  try again in case a local UNIX user is already there.  Also run through 
1463  the username if we fallback to the username only.
1464  ****************************************************************************/
1465  
1466 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1467                              fstring save_username, bool create )
1468 {
1469         struct passwd *pw = NULL;
1470         char *p;
1471         fstring username;
1472         
1473         /* we only save a copy of the username it has been mangled 
1474            by winbindd use default domain */
1475            
1476         save_username[0] = '\0';
1477            
1478         /* don't call map_username() here since it has to be done higher 
1479            up the stack so we don't call it mutliple times */
1480
1481         fstrcpy( username, domuser );
1482         
1483         p = strchr_m( username, *lp_winbind_separator() );
1484         
1485         /* code for a DOMAIN\user string */
1486         
1487         if ( p ) {
1488                 fstring strip_username;
1489
1490                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1491                 if ( pw ) {     
1492                         /* make sure we get the case of the username correct */
1493                         /* work around 'winbind use default domain = yes' */
1494
1495                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1496                                 char *domain;
1497                                 
1498                                 /* split the domain and username into 2 strings */
1499                                 *p = '\0';
1500                                 domain = username;
1501
1502                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1503                         }
1504                         else
1505                                 fstrcpy( save_username, pw->pw_name );
1506
1507                         /* whew -- done! */             
1508                         return pw;
1509                 }
1510
1511                 /* setup for lookup of just the username */
1512                 /* remember that p and username are overlapping memory */
1513
1514                 p++;
1515                 fstrcpy( strip_username, p );
1516                 fstrcpy( username, strip_username );
1517         }
1518         
1519         /* just lookup a plain username */
1520         
1521         pw = Get_Pwnam_alloc(mem_ctx, username);
1522                 
1523         /* Create local user if requested but only if winbindd
1524            is not running.  We need to protect against cases
1525            where winbindd is failing and then prematurely
1526            creating users in /etc/passwd */
1527         
1528         if ( !pw && create && !winbind_ping() ) {
1529                 /* Don't add a machine account. */
1530                 if (username[strlen(username)-1] == '$')
1531                         return NULL;
1532
1533                 smb_create_user(NULL, username, NULL);
1534                 pw = Get_Pwnam_alloc(mem_ctx, username);
1535         }
1536         
1537         /* one last check for a valid passwd struct */
1538         
1539         if ( pw )
1540                 fstrcpy( save_username, pw->pw_name );
1541
1542         return pw;
1543 }
1544
1545 /***************************************************************************
1546  Make a server_info struct from the info3 returned by a domain logon 
1547 ***************************************************************************/
1548
1549 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1550                                 const char *sent_nt_username,
1551                                 const char *domain,
1552                                 auth_serversupplied_info **server_info, 
1553                                 struct netr_SamInfo3 *info3)
1554 {
1555         char zeros[16];
1556
1557         NTSTATUS nt_status = NT_STATUS_OK;
1558         char *found_username = NULL;
1559         const char *nt_domain;
1560         const char *nt_username;
1561         struct samu *sam_account = NULL;
1562         DOM_SID user_sid;
1563         DOM_SID group_sid;
1564         bool username_was_mapped;
1565
1566         uid_t uid = (uid_t)-1;
1567         gid_t gid = (gid_t)-1;
1568
1569         auth_serversupplied_info *result;
1570
1571         /* 
1572            Here is where we should check the list of
1573            trusted domains, and verify that the SID 
1574            matches.
1575         */
1576
1577         sid_copy(&user_sid, info3->base.domain_sid);
1578         if (!sid_append_rid(&user_sid, info3->base.rid)) {
1579                 return NT_STATUS_INVALID_PARAMETER;
1580         }
1581         
1582         sid_copy(&group_sid, info3->base.domain_sid);
1583         if (!sid_append_rid(&group_sid, info3->base.primary_gid)) {
1584                 return NT_STATUS_INVALID_PARAMETER;
1585         }
1586
1587         nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1588         if (!nt_username) {
1589                 /* If the server didn't give us one, just use the one we sent
1590                  * them */
1591                 nt_username = sent_nt_username;
1592         }
1593
1594         nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1595         if (!nt_domain) {
1596                 /* If the server didn't give us one, just use the one we sent
1597                  * them */
1598                 nt_domain = domain;
1599         }
1600         
1601         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1602            add user script (2.2.x behavior).
1603
1604            We use the _unmapped_ username here in an attempt to provide
1605            consistent username mapping behavior between kerberos and NTLM[SSP]
1606            authentication in domain mode security.  I.E. Username mapping
1607            should be applied to the fully qualified username
1608            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1609            called map_username() unnecessarily in make_user_info_map() but
1610            that is how the current code is designed.  Making the change here
1611            is the least disruptive place.  -- jerry */
1612            
1613         if ( !(sam_account = samu_new( NULL )) ) {
1614                 return NT_STATUS_NO_MEMORY;
1615         }
1616
1617         /* this call will try to create the user if necessary */
1618
1619         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1620                                      &found_username, &uid, &gid, sam_account,
1621                                      &username_was_mapped);
1622
1623         
1624         /* if we still don't have a valid unix account check for 
1625           'map to guest = bad uid' */
1626           
1627         if (!NT_STATUS_IS_OK(nt_status)) {
1628                 TALLOC_FREE( sam_account );
1629                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1630                         make_server_info_guest(NULL, server_info);
1631                         return NT_STATUS_OK;
1632                 }
1633                 return nt_status;
1634         }
1635                 
1636         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1637                 TALLOC_FREE(sam_account);
1638                 return NT_STATUS_NO_MEMORY;
1639         }
1640
1641         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1642                 TALLOC_FREE(sam_account);
1643                 return NT_STATUS_NO_MEMORY;
1644         }
1645
1646         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1647                 TALLOC_FREE(sam_account);
1648                 return NT_STATUS_NO_MEMORY;
1649         }
1650
1651         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1652                 TALLOC_FREE(sam_account);
1653                 return NT_STATUS_UNSUCCESSFUL;
1654         }
1655
1656         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1657                 TALLOC_FREE(sam_account);
1658                 return NT_STATUS_UNSUCCESSFUL;
1659         }
1660
1661         if (!pdb_set_fullname(sam_account,
1662                               info3->base.full_name.string,
1663                               PDB_CHANGED)) {
1664                 TALLOC_FREE(sam_account);
1665                 return NT_STATUS_NO_MEMORY;
1666         }
1667
1668         if (!pdb_set_logon_script(sam_account,
1669                                   info3->base.logon_script.string,
1670                                   PDB_CHANGED)) {
1671                 TALLOC_FREE(sam_account);
1672                 return NT_STATUS_NO_MEMORY;
1673         }
1674
1675         if (!pdb_set_profile_path(sam_account,
1676                                   info3->base.profile_path.string,
1677                                   PDB_CHANGED)) {
1678                 TALLOC_FREE(sam_account);
1679                 return NT_STATUS_NO_MEMORY;
1680         }
1681
1682         if (!pdb_set_homedir(sam_account,
1683                              info3->base.home_directory.string,
1684                              PDB_CHANGED)) {
1685                 TALLOC_FREE(sam_account);
1686                 return NT_STATUS_NO_MEMORY;
1687         }
1688
1689         if (!pdb_set_dir_drive(sam_account,
1690                                info3->base.home_drive.string,
1691                                PDB_CHANGED)) {
1692                 TALLOC_FREE(sam_account);
1693                 return NT_STATUS_NO_MEMORY;
1694         }
1695
1696         if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {
1697                 TALLOC_FREE(sam_account);
1698                 return NT_STATUS_NO_MEMORY;
1699         }
1700
1701         if (!pdb_set_pass_last_set_time(
1702                     sam_account,
1703                     nt_time_to_unix(info3->base.last_password_change),
1704                     PDB_CHANGED)) {
1705                 TALLOC_FREE(sam_account);
1706                 return NT_STATUS_NO_MEMORY;
1707         }
1708
1709         if (!pdb_set_pass_can_change_time(
1710                     sam_account,
1711                     nt_time_to_unix(info3->base.allow_password_change),
1712                     PDB_CHANGED)) {
1713                 TALLOC_FREE(sam_account);
1714                 return NT_STATUS_NO_MEMORY;
1715         }
1716
1717         if (!pdb_set_pass_must_change_time(
1718                     sam_account,
1719                     nt_time_to_unix(info3->base.force_password_change),
1720                     PDB_CHANGED)) {
1721                 TALLOC_FREE(sam_account);
1722                 return NT_STATUS_NO_MEMORY;
1723         }
1724
1725         result = make_server_info(NULL);
1726         if (result == NULL) {
1727                 DEBUG(4, ("make_server_info failed!\n"));
1728                 TALLOC_FREE(sam_account);
1729                 return NT_STATUS_NO_MEMORY;
1730         }
1731
1732         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1733            valid struct samu) */
1734                    
1735         result->sam_account = sam_account;
1736         result->unix_name = talloc_strdup(result, found_username);
1737
1738         result->sanitized_username = sanitize_username(result,
1739                                                        result->unix_name);
1740         if (result->sanitized_username == NULL) {
1741                 TALLOC_FREE(result);
1742                 return NT_STATUS_NO_MEMORY;
1743         }
1744
1745         /* Fill in the unix info we found on the way */
1746
1747         result->utok.uid = uid;
1748         result->utok.gid = gid;
1749
1750         /* Create a 'combined' list of all SIDs we might want in the SD */
1751
1752         result->num_sids = 0;
1753         result->sids = NULL;
1754
1755         nt_status = sid_array_from_info3(result, info3,
1756                                          &result->sids,
1757                                          &result->num_sids,
1758                                          false, false);
1759         if (!NT_STATUS_IS_OK(nt_status)) {
1760                 TALLOC_FREE(result);
1761                 return nt_status;
1762         }
1763
1764         /* Ensure the primary group sid is at position 0. */
1765         sort_sid_array_for_smbd(result, &group_sid);
1766
1767         result->login_server = talloc_strdup(result,
1768                                              info3->base.logon_server.string);
1769
1770         /* ensure we are never given NULL session keys */
1771
1772         ZERO_STRUCT(zeros);
1773
1774         if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1775                 result->user_session_key = data_blob_null;
1776         } else {
1777                 result->user_session_key = data_blob_talloc(
1778                         result, info3->base.key.key,
1779                         sizeof(info3->base.key.key));
1780         }
1781
1782         if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1783                 result->lm_session_key = data_blob_null;
1784         } else {
1785                 result->lm_session_key = data_blob_talloc(
1786                         result, info3->base.LMSessKey.key,
1787                         sizeof(info3->base.LMSessKey.key));
1788         }
1789
1790         result->nss_token |= username_was_mapped;
1791
1792         *server_info = result;
1793
1794         return NT_STATUS_OK;
1795 }
1796
1797 /*****************************************************************************
1798  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1799 ******************************************************************************/
1800
1801 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1802                                           const char *sent_nt_username,
1803                                           const char *domain,
1804                                           const struct wbcAuthUserInfo *info,
1805                                           auth_serversupplied_info **server_info)
1806 {
1807         char zeros[16];
1808
1809         NTSTATUS nt_status = NT_STATUS_OK;
1810         char *found_username = NULL;
1811         const char *nt_domain;
1812         const char *nt_username;
1813         struct samu *sam_account = NULL;
1814         DOM_SID user_sid;
1815         DOM_SID group_sid;
1816         bool username_was_mapped;
1817         uint32_t i;
1818
1819         uid_t uid = (uid_t)-1;
1820         gid_t gid = (gid_t)-1;
1821
1822         auth_serversupplied_info *result;
1823
1824         result = make_server_info(NULL);
1825         if (result == NULL) {
1826                 DEBUG(4, ("make_server_info failed!\n"));
1827                 return NT_STATUS_NO_MEMORY;
1828         }
1829
1830         /*
1831            Here is where we should check the list of
1832            trusted domains, and verify that the SID
1833            matches.
1834         */
1835
1836         memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
1837         memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
1838
1839         if (info->account_name) {
1840                 nt_username = talloc_strdup(result, info->account_name);
1841         } else {
1842                 /* If the server didn't give us one, just use the one we sent
1843                  * them */
1844                 nt_username = talloc_strdup(result, sent_nt_username);
1845         }
1846         if (!nt_username) {
1847                 TALLOC_FREE(result);
1848                 return NT_STATUS_NO_MEMORY;
1849         }
1850
1851         if (info->domain_name) {
1852                 nt_domain = talloc_strdup(result, info->domain_name);
1853         } else {
1854                 /* If the server didn't give us one, just use the one we sent
1855                  * them */
1856                 nt_domain = talloc_strdup(result, domain);
1857         }
1858         if (!nt_domain) {
1859                 TALLOC_FREE(result);
1860                 return NT_STATUS_NO_MEMORY;
1861         }
1862
1863         /* try to fill the SAM account..  If getpwnam() fails, then try the
1864            add user script (2.2.x behavior).
1865
1866            We use the _unmapped_ username here in an attempt to provide
1867            consistent username mapping behavior between kerberos and NTLM[SSP]
1868            authentication in domain mode security.  I.E. Username mapping
1869            should be applied to the fully qualified username
1870            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1871            called map_username() unnecessarily in make_user_info_map() but
1872            that is how the current code is designed.  Making the change here
1873            is the least disruptive place.  -- jerry */
1874
1875         if ( !(sam_account = samu_new( result )) ) {
1876                 TALLOC_FREE(result);
1877                 return NT_STATUS_NO_MEMORY;
1878         }
1879
1880         /* this call will try to create the user if necessary */
1881
1882         nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
1883                                      &found_username, &uid, &gid, sam_account,
1884                                      &username_was_mapped);
1885
1886         /* if we still don't have a valid unix account check for
1887           'map to guest = bad uid' */
1888
1889         if (!NT_STATUS_IS_OK(nt_status)) {
1890                 TALLOC_FREE( result );
1891                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1892                         make_server_info_guest(NULL, server_info);
1893                         return NT_STATUS_OK;
1894                 }
1895                 return nt_status;
1896         }
1897
1898         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1899                 TALLOC_FREE(result);
1900                 return NT_STATUS_NO_MEMORY;
1901         }
1902
1903         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1904                 TALLOC_FREE(result);
1905                 return NT_STATUS_NO_MEMORY;
1906         }
1907
1908         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1909                 TALLOC_FREE(result);
1910                 return NT_STATUS_NO_MEMORY;
1911         }
1912
1913         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1914                 TALLOC_FREE(result);
1915                 return NT_STATUS_UNSUCCESSFUL;
1916         }
1917
1918         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1919                 TALLOC_FREE(result);
1920                 return NT_STATUS_UNSUCCESSFUL;
1921         }
1922
1923         if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
1924                 TALLOC_FREE(result);
1925                 return NT_STATUS_NO_MEMORY;
1926         }
1927
1928         if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
1929                 TALLOC_FREE(result);
1930                 return NT_STATUS_NO_MEMORY;
1931         }
1932
1933         if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
1934                 TALLOC_FREE(result);
1935                 return NT_STATUS_NO_MEMORY;
1936         }
1937
1938         if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
1939                 TALLOC_FREE(result);
1940                 return NT_STATUS_NO_MEMORY;
1941         }
1942
1943         if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
1944                 TALLOC_FREE(result);
1945                 return NT_STATUS_NO_MEMORY;
1946         }
1947
1948         if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
1949                 TALLOC_FREE(result);
1950                 return NT_STATUS_NO_MEMORY;
1951         }
1952
1953         if (!pdb_set_pass_last_set_time(
1954                     sam_account,
1955                     nt_time_to_unix(info->pass_last_set_time),
1956                     PDB_CHANGED)) {
1957                 TALLOC_FREE(result);
1958                 return NT_STATUS_NO_MEMORY;
1959         }
1960
1961         if (!pdb_set_pass_can_change_time(
1962                     sam_account,
1963                     nt_time_to_unix(info->pass_can_change_time),
1964                     PDB_CHANGED)) {
1965                 TALLOC_FREE(result);
1966                 return NT_STATUS_NO_MEMORY;
1967         }
1968
1969         if (!pdb_set_pass_must_change_time(
1970                     sam_account,
1971                     nt_time_to_unix(info->pass_must_change_time),
1972                     PDB_CHANGED)) {
1973                 TALLOC_FREE(result);
1974                 return NT_STATUS_NO_MEMORY;
1975         }
1976
1977         /* save this here to _net_sam_logon() doesn't fail (it assumes a
1978            valid struct samu) */
1979
1980         result->sam_account = sam_account;
1981         result->unix_name = talloc_strdup(result, found_username);
1982
1983         result->sanitized_username = sanitize_username(result,
1984                                                        result->unix_name);
1985         result->login_server = talloc_strdup(result, info->logon_server);
1986
1987         if ((result->unix_name == NULL)
1988             || (result->sanitized_username == NULL)
1989             || (result->login_server == NULL)) {
1990                 TALLOC_FREE(result);
1991                 return NT_STATUS_NO_MEMORY;
1992         }
1993
1994         /* Fill in the unix info we found on the way */
1995
1996         result->utok.uid = uid;
1997         result->utok.gid = gid;
1998
1999         /* Create a 'combined' list of all SIDs we might want in the SD */
2000
2001         result->num_sids = info->num_sids - 2;
2002         result->sids = talloc_array(result, DOM_SID, result->num_sids);
2003         if (result->sids == NULL) {
2004                 TALLOC_FREE(result);
2005                 return NT_STATUS_NO_MEMORY;
2006         }
2007
2008         for (i=0; i < result->num_sids; i++) {
2009                 memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
2010         }
2011
2012         /* Ensure the primary group sid is at position 0. */
2013         sort_sid_array_for_smbd(result, &group_sid);
2014
2015         /* ensure we are never given NULL session keys */
2016
2017         ZERO_STRUCT(zeros);
2018
2019         if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
2020                 result->user_session_key = data_blob_null;
2021         } else {
2022                 result->user_session_key = data_blob_talloc(
2023                         result, info->user_session_key,
2024                         sizeof(info->user_session_key));
2025         }
2026
2027         if (memcmp(info->lm_session_key, zeros, 8) == 0) {
2028                 result->lm_session_key = data_blob_null;
2029         } else {
2030                 result->lm_session_key = data_blob_talloc(
2031                         result, info->lm_session_key,
2032                         sizeof(info->lm_session_key));
2033         }
2034
2035         result->nss_token |= username_was_mapped;
2036
2037         *server_info = result;
2038
2039         return NT_STATUS_OK;
2040 }
2041
2042 /***************************************************************************
2043  Free a user_info struct
2044 ***************************************************************************/
2045
2046 void free_user_info(auth_usersupplied_info **user_info)
2047 {
2048         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
2049         if (*user_info != NULL) {
2050                 if ((*user_info)->smb_name) {
2051                         DEBUG(10,("structure was created for %s\n",
2052                                   (*user_info)->smb_name));
2053                 }
2054                 SAFE_FREE((*user_info)->smb_name);
2055                 SAFE_FREE((*user_info)->internal_username);
2056                 SAFE_FREE((*user_info)->client_domain);
2057                 SAFE_FREE((*user_info)->domain);
2058                 SAFE_FREE((*user_info)->wksta_name);
2059                 data_blob_free(&(*user_info)->lm_resp);
2060                 data_blob_free(&(*user_info)->nt_resp);
2061                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
2062                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
2063                 data_blob_clear_free(&(*user_info)->plaintext_password);
2064                 ZERO_STRUCT(**user_info);
2065         }
2066         SAFE_FREE(*user_info);
2067 }
2068
2069 /***************************************************************************
2070  Make an auth_methods struct
2071 ***************************************************************************/
2072
2073 bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
2074 {
2075         if (!auth_context) {
2076                 smb_panic("no auth_context supplied to "
2077                           "make_auth_methods()!\n");
2078         }
2079
2080         if (!auth_method) {
2081                 smb_panic("make_auth_methods: pointer to auth_method pointer "
2082                           "is NULL!\n");
2083         }
2084
2085         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
2086         if (!*auth_method) {
2087                 DEBUG(0,("make_auth_method: malloc failed!\n"));
2088                 return False;
2089         }
2090         ZERO_STRUCTP(*auth_method);
2091         
2092         return True;
2093 }
2094
2095 /**
2096  * Verify whether or not given domain is trusted.
2097  *
2098  * @param domain_name name of the domain to be verified
2099  * @return true if domain is one of the trusted once or
2100  *         false if otherwise
2101  **/
2102
2103 bool is_trusted_domain(const char* dom_name)
2104 {
2105         DOM_SID trustdom_sid;
2106         bool ret;
2107
2108         /* no trusted domains for a standalone server */
2109
2110         if ( lp_server_role() == ROLE_STANDALONE )
2111                 return False;
2112
2113         /* if we are a DC, then check for a direct trust relationships */
2114
2115         if ( IS_DC ) {
2116                 become_root();
2117                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2118                           "[%s]\n", dom_name ));
2119                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2120                 unbecome_root();
2121                 if (ret)
2122                         return True;
2123         }
2124         else {
2125                 wbcErr result;
2126
2127                 /* If winbind is around, ask it */
2128
2129                 result = wb_is_trusted_domain(dom_name);
2130
2131                 if (result == WBC_ERR_SUCCESS) {
2132                         return True;
2133                 }
2134
2135                 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
2136                         /* winbind could not find the domain */
2137                         return False;
2138                 }
2139
2140                 /* The only other possible result is that winbind is not up
2141                    and running. We need to update the trustdom_cache
2142                    ourselves */
2143                 
2144                 update_trustdom_cache();
2145         }
2146
2147         /* now the trustdom cache should be available a DC could still
2148          * have a transitive trust so fall back to the cache of trusted
2149          * domains (like a domain member would use  */
2150
2151         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
2152                 return True;
2153         }
2154
2155         return False;
2156 }
2157