Revert the 3.3.5 merge which I did in an unclean copy of the trunk..:-(
[abartlet/samba-debian.git] / source / 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         const char *username = pdb_get_username(sampass);
559         NTSTATUS status;
560
561         if ( !(result = make_server_info(NULL)) ) {
562                 return NT_STATUS_NO_MEMORY;
563         }
564
565         if ( !(pwd = getpwnam_alloc(result, username)) ) {
566                 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
567                           pdb_get_username(sampass)));
568                 TALLOC_FREE(result);
569                 return NT_STATUS_NO_SUCH_USER;
570         }
571
572         result->sam_account = sampass;
573         result->unix_name = pwd->pw_name;
574         /* Ensure that we keep pwd->pw_name, because we will free pwd below */
575         talloc_steal(result, pwd->pw_name);
576         result->utok.gid = pwd->pw_gid;
577         result->utok.uid = pwd->pw_uid;
578
579         TALLOC_FREE(pwd);
580
581         result->sanitized_username = sanitize_username(result,
582                                                        result->unix_name);
583         if (result->sanitized_username == NULL) {
584                 TALLOC_FREE(result);
585                 return NT_STATUS_NO_MEMORY;
586         }
587
588         if (IS_DC && is_our_machine_account(username)) {
589                 /*
590                  * Ensure for a connection from our own
591                  * machine account (from winbindd on a DC)
592                  * there are no supplementary groups.
593                  * Prevents loops in calling gid_to_sid().
594                  */
595                 result->sids = NULL;
596                 gids = NULL;
597                 result->num_sids = 0;
598
599                 /*
600                  * This is a hack of monstrous proportions.
601                  * If we know it's winbindd talking to us,
602                  * we know we must never recurse into it,
603                  * so turn off contacting winbindd for this
604                  * entire process. This will get fixed when
605                  * winbindd doesn't need to talk to smbd on
606                  * a PDC. JRA.
607                  */
608
609                 (void)winbind_off();
610
611                 DEBUG(10, ("make_server_info_sam: our machine account %s "
612                         "setting supplementary group list empty and "
613                         "turning off winbindd requests.\n",
614                         username));
615         } else {
616                 status = pdb_enum_group_memberships(result, sampass,
617                                             &result->sids, &gids,
618                                             &result->num_sids);
619
620                 if (!NT_STATUS_IS_OK(status)) {
621                         DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
622                                    nt_errstr(status)));
623                         result->sam_account = NULL; /* Don't free on error exit. */
624                         TALLOC_FREE(result);
625                         return status;
626                 }
627         }
628
629         /* For now we throw away the gids and convert via sid_to_gid
630          * later. This needs fixing, but I'd like to get the code straight and
631          * simple first. */
632          
633         TALLOC_FREE(gids);
634
635         DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
636                  pdb_get_username(sampass), result->unix_name));
637
638         *server_info = result;
639         /* Ensure thaat the sampass will be freed with the result */
640         talloc_steal(result, sampass);
641
642         return NT_STATUS_OK;
643 }
644
645 static NTSTATUS log_nt_token(NT_USER_TOKEN *token)
646 {
647         TALLOC_CTX *frame = talloc_stackframe();
648         char *command;
649         char *group_sidstr;
650         size_t i;
651
652         if ((lp_log_nt_token_command() == NULL) ||
653             (strlen(lp_log_nt_token_command()) == 0)) {
654                 TALLOC_FREE(frame);
655                 return NT_STATUS_OK;
656         }
657
658         group_sidstr = talloc_strdup(frame, "");
659         for (i=1; i<token->num_sids; i++) {
660                 group_sidstr = talloc_asprintf(
661                         frame, "%s %s", group_sidstr,
662                         sid_string_talloc(frame, &token->user_sids[i]));
663         }
664
665         command = talloc_string_sub(
666                 frame, lp_log_nt_token_command(),
667                 "%s", sid_string_talloc(frame, &token->user_sids[0]));
668         command = talloc_string_sub(frame, command, "%t", group_sidstr);
669
670         if (command == NULL) {
671                 TALLOC_FREE(frame);
672                 return NT_STATUS_NO_MEMORY;
673         }
674
675         DEBUG(8, ("running command: [%s]\n", command));
676         if (smbrun(command, NULL) != 0) {
677                 DEBUG(0, ("Could not log NT token\n"));
678                 TALLOC_FREE(frame);
679                 return NT_STATUS_ACCESS_DENIED;
680         }
681
682         TALLOC_FREE(frame);
683         return NT_STATUS_OK;
684 }
685
686 /*
687  * Create the token to use from server_info->sam_account and
688  * server_info->sids (the info3/sam groups). Find the unix gids.
689  */
690
691 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
692 {
693         NTSTATUS status;
694         size_t i;
695         struct dom_sid tmp_sid;
696
697         /*
698          * If winbind is not around, we can not make much use of the SIDs the
699          * domain controller provided us with. Likewise if the user name was
700          * mapped to some local unix user.
701          */
702
703         if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
704             (server_info->nss_token)) {
705                 status = create_token_from_username(server_info,
706                                                     server_info->unix_name,
707                                                     server_info->guest,
708                                                     &server_info->utok.uid,
709                                                     &server_info->utok.gid,
710                                                     &server_info->unix_name,
711                                                     &server_info->ptok);
712
713         } else {
714                 server_info->ptok = create_local_nt_token(
715                         server_info,
716                         pdb_get_user_sid(server_info->sam_account),
717                         server_info->guest,
718                         server_info->num_sids, server_info->sids);
719                 status = server_info->ptok ?
720                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
721         }
722
723         if (!NT_STATUS_IS_OK(status)) {
724                 return status;
725         }
726
727         /* Convert the SIDs to gids. */
728
729         server_info->utok.ngroups = 0;
730         server_info->utok.groups = NULL;
731
732         /* Start at index 1, where the groups start. */
733
734         for (i=1; i<server_info->ptok->num_sids; i++) {
735                 gid_t gid;
736                 DOM_SID *sid = &server_info->ptok->user_sids[i];
737
738                 if (!sid_to_gid(sid, &gid)) {
739                         DEBUG(10, ("Could not convert SID %s to gid, "
740                                    "ignoring it\n", sid_string_dbg(sid)));
741                         continue;
742                 }
743                 add_gid_to_array_unique(server_info, gid,
744                                         &server_info->utok.groups,
745                                         &server_info->utok.ngroups);
746         }
747
748         /*
749          * Add the "Unix Group" SID for each gid to catch mapped groups
750          * and their Unix equivalent.  This is to solve the backwards
751          * compatibility problem of 'valid users = +ntadmin' where
752          * ntadmin has been paired with "Domain Admins" in the group
753          * mapping table.  Otherwise smb.conf would need to be changed
754          * to 'valid user = "Domain Admins"'.  --jerry
755          *
756          * For consistency we also add the "Unix User" SID,
757          * so that the complete unix token is represented within
758          * the nt token.
759          */
760
761         if (!uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid)) {
762                 DEBUG(1,("create_local_token: Failed to create SID "
763                         "for uid %d!\n", server_info->utok.uid));
764         }
765         add_sid_to_array_unique(server_info->ptok, &tmp_sid,
766                                 &server_info->ptok->user_sids,
767                                 &server_info->ptok->num_sids);
768
769         for ( i=0; i<server_info->utok.ngroups; i++ ) {
770                 if (!gid_to_unix_groups_sid( server_info->utok.groups[i], &tmp_sid ) ) {
771                         DEBUG(1,("create_local_token: Failed to create SID "
772                                 "for gid %d!\n", server_info->utok.groups[i]));
773                         continue;
774                 }
775                 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
776                                         &server_info->ptok->user_sids,
777                                         &server_info->ptok->num_sids);
778         }
779
780         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
781         debug_unix_user_token(DBGC_AUTH, 10,
782                               server_info->utok.uid,
783                               server_info->utok.gid,
784                               server_info->utok.ngroups,
785                               server_info->utok.groups);
786
787         status = log_nt_token(server_info->ptok);
788         return status;
789 }
790
791 /*
792  * Create an artificial NT token given just a username. (Initially intended
793  * for force user)
794  *
795  * We go through lookup_name() to avoid problems we had with 'winbind use
796  * default domain'.
797  *
798  * We have 3 cases:
799  *
800  * unmapped unix users: Go directly to nss to find the user's group.
801  *
802  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
803  *
804  * If the user is provided by winbind, the primary gid is set to "domain
805  * users" of the user's domain. For an explanation why this is necessary, see
806  * the thread starting at
807  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
808  */
809
810 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
811                                     bool is_guest,
812                                     uid_t *uid, gid_t *gid,
813                                     char **found_username,
814                                     struct nt_user_token **token)
815 {
816         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
817         TALLOC_CTX *tmp_ctx;
818         DOM_SID user_sid;
819         enum lsa_SidType type;
820         gid_t *gids;
821         DOM_SID *group_sids;
822         DOM_SID unix_group_sid;
823         size_t num_group_sids;
824         size_t num_gids;
825         size_t i;
826
827         tmp_ctx = talloc_new(NULL);
828         if (tmp_ctx == NULL) {
829                 DEBUG(0, ("talloc_new failed\n"));
830                 return NT_STATUS_NO_MEMORY;
831         }
832
833         if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
834                          NULL, NULL, &user_sid, &type)) {
835                 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
836                 goto done;
837         }
838
839         if (type != SID_NAME_USER) {
840                 DEBUG(1, ("%s is a %s, not a user\n", username,
841                           sid_type_lookup(type)));
842                 goto done;
843         }
844
845         if (sid_check_is_in_our_domain(&user_sid)) {
846                 bool ret;
847
848                 /* This is a passdb user, so ask passdb */
849
850                 struct samu *sam_acct = NULL;
851
852                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
853                         result = NT_STATUS_NO_MEMORY;
854                         goto done;
855                 }
856
857                 become_root();
858                 ret = pdb_getsampwsid(sam_acct, &user_sid);
859                 unbecome_root();
860
861                 if (!ret) {
862                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
863                                   sid_string_dbg(&user_sid), username));
864                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
865                         goto unix_user;
866                 }
867
868                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
869                                                     &group_sids, &gids,
870                                                     &num_group_sids);
871                 if (!NT_STATUS_IS_OK(result)) {
872                         DEBUG(10, ("enum_group_memberships failed for %s\n",
873                                    username));
874                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
875                         goto unix_user;
876                 }
877
878                 /* see the smb_panic() in pdb_default_enum_group_memberships */
879                 SMB_ASSERT(num_group_sids > 0); 
880
881                 *gid = gids[0];
882
883                 /* Ensure we're returning the found_username on the right context. */
884                 *found_username = talloc_strdup(mem_ctx,
885                                                 pdb_get_username(sam_acct));
886
887         } else  if (sid_check_is_in_unix_users(&user_sid)) {
888
889                 /* This is a unix user not in passdb. We need to ask nss
890                  * directly, without consulting passdb */
891
892                 struct passwd *pass;
893
894                 /*
895                  * This goto target is used as a fallback for the passdb
896                  * case. The concrete bug report is when passdb gave us an
897                  * unmapped gid.
898                  */
899
900         unix_user:
901
902                 if (!sid_to_uid(&user_sid, uid)) {
903                         DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
904                                   username, sid_string_dbg(&user_sid)));
905                         goto done;
906                 }
907
908                 uid_to_unix_users_sid(*uid, &user_sid);
909
910                 pass = getpwuid_alloc(tmp_ctx, *uid);
911                 if (pass == NULL) {
912                         DEBUG(1, ("getpwuid(%d) for user %s failed\n",
913                                   *uid, username));
914                         goto done;
915                 }
916
917                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
918                                          &gids, &num_group_sids)) {
919                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
920                                   username));
921                         goto done;
922                 }
923
924                 if (num_group_sids) {
925                         group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
926                         if (group_sids == NULL) {
927                                 DEBUG(1, ("TALLOC_ARRAY failed\n"));
928                                 result = NT_STATUS_NO_MEMORY;
929                                 goto done;
930                         }
931                 } else {
932                         group_sids = NULL;
933                 }
934
935                 for (i=0; i<num_group_sids; i++) {
936                         gid_to_sid(&group_sids[i], gids[i]);
937                 }
938
939                 /* In getgroups_unix_user we always set the primary gid */
940                 SMB_ASSERT(num_group_sids > 0); 
941
942                 *gid = gids[0];
943
944                 /* Ensure we're returning the found_username on the right context. */
945                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
946         } else {
947
948                 /* This user is from winbind, force the primary gid to the
949                  * user's "domain users" group. Under certain circumstances
950                  * (user comes from NT4), this might be a loss of
951                  * information. But we can not rely on winbind getting the
952                  * correct info. AD might prohibit winbind looking up that
953                  * information. */
954
955                 uint32 dummy;
956
957                 num_group_sids = 1;
958                 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
959                 if (group_sids == NULL) {
960                         DEBUG(1, ("TALLOC_ARRAY failed\n"));
961                         result = NT_STATUS_NO_MEMORY;
962                         goto done;
963                 }
964
965                 sid_copy(&group_sids[0], &user_sid);
966                 sid_split_rid(&group_sids[0], &dummy);
967                 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
968
969                 if (!sid_to_gid(&group_sids[0], gid)) {
970                         DEBUG(1, ("sid_to_gid(%s) failed\n",
971                                   sid_string_dbg(&group_sids[0])));
972                         goto done;
973                 }
974
975                 gids = gid;
976
977                 /* Ensure we're returning the found_username on the right context. */
978                 *found_username = talloc_strdup(mem_ctx, username);
979         }
980
981         /* Add the "Unix Group" SID for each gid to catch mapped groups
982            and their Unix equivalent.  This is to solve the backwards
983            compatibility problem of 'valid users = +ntadmin' where
984            ntadmin has been paired with "Domain Admins" in the group
985            mapping table.  Otherwise smb.conf would need to be changed
986            to 'valid user = "Domain Admins"'.  --jerry */
987
988         num_gids = num_group_sids;
989         for ( i=0; i<num_gids; i++ ) {
990                 gid_t high, low;
991
992                 /* don't pickup anything managed by Winbind */
993
994                 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
995                         continue;
996
997                 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
998                         DEBUG(1,("create_token_from_username: Failed to create SID "
999                                 "for gid %d!\n", gids[i]));
1000                         continue;
1001                 }
1002                 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
1003                                                  &group_sids, &num_group_sids);
1004                 if (!NT_STATUS_IS_OK(result)) {
1005                         goto done;
1006                 }
1007         }
1008
1009         /* Ensure we're creating the nt_token on the right context. */
1010         *token = create_local_nt_token(mem_ctx, &user_sid,
1011                                        is_guest, num_group_sids, group_sids);
1012
1013         if ((*token == NULL) || (*found_username == NULL)) {
1014                 result = NT_STATUS_NO_MEMORY;
1015                 goto done;
1016         }
1017
1018         result = NT_STATUS_OK;
1019  done:
1020         TALLOC_FREE(tmp_ctx);
1021         return result;
1022 }
1023
1024 /***************************************************************************
1025  Build upon create_token_from_username:
1026
1027  Expensive helper function to figure out whether a user given its name is
1028  member of a particular group.
1029 ***************************************************************************/
1030
1031 bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
1032 {
1033         NTSTATUS status;
1034         uid_t uid;
1035         gid_t gid;
1036         char *found_username;
1037         struct nt_user_token *token;
1038         bool result;
1039
1040         TALLOC_CTX *mem_ctx;
1041
1042         mem_ctx = talloc_new(NULL);
1043         if (mem_ctx == NULL) {
1044                 DEBUG(0, ("talloc_new failed\n"));
1045                 return False;
1046         }
1047
1048         status = create_token_from_username(mem_ctx, username, False,
1049                                             &uid, &gid, &found_username,
1050                                             &token);
1051
1052         if (!NT_STATUS_IS_OK(status)) {
1053                 DEBUG(10, ("could not create token for %s\n", username));
1054                 return False;
1055         }
1056
1057         result = nt_token_check_sid(group_sid, token);
1058
1059         TALLOC_FREE(mem_ctx);
1060         return result;
1061         
1062 }
1063
1064 bool user_in_group(const char *username, const char *groupname)
1065 {
1066         TALLOC_CTX *mem_ctx;
1067         DOM_SID group_sid;
1068         bool ret;
1069
1070         mem_ctx = talloc_new(NULL);
1071         if (mem_ctx == NULL) {
1072                 DEBUG(0, ("talloc_new failed\n"));
1073                 return False;
1074         }
1075
1076         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1077                           NULL, NULL, &group_sid, NULL);
1078         TALLOC_FREE(mem_ctx);
1079
1080         if (!ret) {
1081                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1082                 return False;
1083         }
1084
1085         return user_in_group_sid(username, &group_sid);
1086 }
1087
1088 /***************************************************************************
1089  Make (and fill) a server_info struct from a 'struct passwd' by conversion
1090  to a struct samu
1091 ***************************************************************************/
1092
1093 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
1094                              char *unix_username,
1095                              struct passwd *pwd)
1096 {
1097         NTSTATUS status;
1098         struct samu *sampass = NULL;
1099         gid_t *gids;
1100         char *qualified_name = NULL;
1101         TALLOC_CTX *mem_ctx = NULL;
1102         DOM_SID u_sid;
1103         enum lsa_SidType type;
1104         auth_serversupplied_info *result;
1105         
1106         if ( !(sampass = samu_new( NULL )) ) {
1107                 return NT_STATUS_NO_MEMORY;
1108         }
1109         
1110         status = samu_set_unix( sampass, pwd );
1111         if (!NT_STATUS_IS_OK(status)) {
1112                 return status;
1113         }
1114
1115         result = make_server_info(NULL);
1116         if (result == NULL) {
1117                 TALLOC_FREE(sampass);
1118                 return NT_STATUS_NO_MEMORY;
1119         }
1120
1121         result->sam_account = sampass;
1122
1123         result->unix_name = talloc_strdup(result, unix_username);
1124         result->sanitized_username = sanitize_username(result, unix_username);
1125
1126         if ((result->unix_name == NULL)
1127             || (result->sanitized_username == NULL)) {
1128                 TALLOC_FREE(sampass);
1129                 TALLOC_FREE(result);
1130                 return NT_STATUS_NO_MEMORY;
1131         }
1132
1133         result->utok.uid = pwd->pw_uid;
1134         result->utok.gid = pwd->pw_gid;
1135
1136         status = pdb_enum_group_memberships(result, sampass,
1137                                             &result->sids, &gids,
1138                                             &result->num_sids);
1139
1140         if (!NT_STATUS_IS_OK(status)) {
1141                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1142                            nt_errstr(status)));
1143                 TALLOC_FREE(result);
1144                 return status;
1145         }
1146
1147         /*
1148          * The SID returned in server_info->sam_account is based
1149          * on our SAM sid even though for a pure UNIX account this should
1150          * not be the case as it doesn't really exist in the SAM db.
1151          * This causes lookups on "[in]valid users" to fail as they
1152          * will lookup this name as a "Unix User" SID to check against
1153          * the user token. Fix this by adding the "Unix User"\unix_username
1154          * SID to the sid array. The correct fix should probably be
1155          * changing the server_info->sam_account user SID to be a
1156          * S-1-22 Unix SID, but this might break old configs where
1157          * plaintext passwords were used with no SAM backend.
1158          */
1159
1160         mem_ctx = talloc_init("make_server_info_pw_tmp");
1161         if (!mem_ctx) {
1162                 TALLOC_FREE(result);
1163                 return NT_STATUS_NO_MEMORY;
1164         }
1165
1166         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
1167                                         unix_users_domain_name(),
1168                                         unix_username );
1169         if (!qualified_name) {
1170                 TALLOC_FREE(result);
1171                 TALLOC_FREE(mem_ctx);
1172                 return NT_STATUS_NO_MEMORY;
1173         }
1174
1175         if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
1176                                                 NULL, NULL,
1177                                                 &u_sid, &type)) {
1178                 TALLOC_FREE(result);
1179                 TALLOC_FREE(mem_ctx);
1180                 return NT_STATUS_NO_SUCH_USER;
1181         }
1182
1183         TALLOC_FREE(mem_ctx);
1184
1185         if (type != SID_NAME_USER) {
1186                 TALLOC_FREE(result);
1187                 return NT_STATUS_NO_SUCH_USER;
1188         }
1189
1190         status = add_sid_to_array_unique(result, &u_sid,
1191                                          &result->sids,
1192                                          &result->num_sids);
1193         if (!NT_STATUS_IS_OK(status)) {
1194                 TALLOC_FREE(result);
1195                 return status;
1196         }
1197
1198         /* For now we throw away the gids and convert via sid_to_gid
1199          * later. This needs fixing, but I'd like to get the code straight and
1200          * simple first. */
1201         TALLOC_FREE(gids);
1202
1203         *server_info = result;
1204
1205         return NT_STATUS_OK;
1206 }
1207
1208 /***************************************************************************
1209  Make (and fill) a user_info struct for a guest login.
1210  This *must* succeed for smbd to start. If there is no mapping entry for
1211  the guest gid, then create one.
1212 ***************************************************************************/
1213
1214 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1215 {
1216         NTSTATUS status;
1217         struct samu *sampass = NULL;
1218         DOM_SID guest_sid;
1219         bool ret;
1220         char zeros[16];
1221         fstring tmp;
1222
1223         if ( !(sampass = samu_new( NULL )) ) {
1224                 return NT_STATUS_NO_MEMORY;
1225         }
1226
1227         sid_copy(&guest_sid, get_global_sam_sid());
1228         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1229
1230         become_root();
1231         ret = pdb_getsampwsid(sampass, &guest_sid);
1232         unbecome_root();
1233
1234         if (!ret) {
1235                 TALLOC_FREE(sampass);
1236                 return NT_STATUS_NO_SUCH_USER;
1237         }
1238
1239         status = make_server_info_sam(server_info, sampass);
1240         if (!NT_STATUS_IS_OK(status)) {
1241                 TALLOC_FREE(sampass);
1242                 return status;
1243         }
1244         
1245         (*server_info)->guest = True;
1246
1247         status = create_local_token(*server_info);
1248         if (!NT_STATUS_IS_OK(status)) {
1249                 DEBUG(10, ("create_local_token failed: %s\n",
1250                            nt_errstr(status)));
1251                 return status;
1252         }
1253
1254         /* annoying, but the Guest really does have a session key, and it is
1255            all zeros! */
1256         ZERO_STRUCT(zeros);
1257         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1258         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1259
1260         alpha_strcpy(tmp, pdb_get_username(sampass), ". _-$", sizeof(tmp));
1261         (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp);
1262
1263         return NT_STATUS_OK;
1264 }
1265
1266 /****************************************************************************
1267   Fake a auth_serversupplied_info just from a username
1268 ****************************************************************************/
1269
1270 NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
1271                                        const char *username,
1272                                        bool is_guest,
1273                                        struct auth_serversupplied_info **presult)
1274 {
1275         struct auth_serversupplied_info *result;
1276         struct passwd *pwd;
1277         NTSTATUS status;
1278
1279         pwd = getpwnam_alloc(talloc_tos(), username);
1280         if (pwd == NULL) {
1281                 return NT_STATUS_NO_SUCH_USER;
1282         }
1283
1284         status = make_server_info_pw(&result, pwd->pw_name, pwd);
1285
1286         TALLOC_FREE(pwd);
1287
1288         if (!NT_STATUS_IS_OK(status)) {
1289                 return status;
1290         }
1291
1292         result->nss_token = true;
1293         result->guest = is_guest;
1294
1295         status = create_local_token(result);
1296
1297         if (!NT_STATUS_IS_OK(status)) {
1298                 TALLOC_FREE(result);
1299                 return status;
1300         }
1301
1302         *presult = result;
1303         return NT_STATUS_OK;
1304 }
1305
1306
1307 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
1308                                                  const auth_serversupplied_info *src)
1309 {
1310         auth_serversupplied_info *dst;
1311
1312         dst = make_server_info(mem_ctx);
1313         if (dst == NULL) {
1314                 return NULL;
1315         }
1316
1317         dst->guest = src->guest;
1318         dst->utok.uid = src->utok.uid;
1319         dst->utok.gid = src->utok.gid;
1320         dst->utok.ngroups = src->utok.ngroups;
1321         if (src->utok.ngroups != 0) {
1322                 dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
1323                         dst, src->utok.groups,
1324                         sizeof(gid_t)*dst->utok.ngroups);
1325         } else {
1326                 dst->utok.groups = NULL;
1327         }
1328
1329         if (src->ptok) {
1330                 dst->ptok = dup_nt_token(dst, src->ptok);
1331                 if (!dst->ptok) {
1332                         TALLOC_FREE(dst);
1333                         return NULL;
1334                 }
1335         }
1336         
1337         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1338                                                 src->user_session_key.length);
1339
1340         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1341                                                 src->lm_session_key.length);
1342
1343         dst->sam_account = samu_new(NULL);
1344         if (!dst->sam_account) {
1345                 TALLOC_FREE(dst);
1346                 return NULL;
1347         }
1348
1349         if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1350                 TALLOC_FREE(dst);
1351                 return NULL;
1352         }
1353         
1354         dst->pam_handle = NULL;
1355         dst->unix_name = talloc_strdup(dst, src->unix_name);
1356         if (!dst->unix_name) {
1357                 TALLOC_FREE(dst);
1358                 return NULL;
1359         }
1360
1361         dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
1362         if (!dst->sanitized_username) {
1363                 TALLOC_FREE(dst);
1364                 return NULL;
1365         }
1366
1367         return dst;
1368 }
1369
1370 /*
1371  * Set a new session key. Used in the rpc server where we have to override the
1372  * SMB level session key with SystemLibraryDTC
1373  */
1374
1375 bool server_info_set_session_key(struct auth_serversupplied_info *info,
1376                                  DATA_BLOB session_key)
1377 {
1378         TALLOC_FREE(info->user_session_key.data);
1379
1380         info->user_session_key = data_blob_talloc(
1381                 info, session_key.data, session_key.length);
1382
1383         return (info->user_session_key.data != NULL);
1384 }
1385
1386 static auth_serversupplied_info *guest_info = NULL;
1387
1388 bool init_guest_info(void)
1389 {
1390         if (guest_info != NULL)
1391                 return True;
1392
1393         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1394 }
1395
1396 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1397                                 auth_serversupplied_info **server_info)
1398 {
1399         *server_info = copy_serverinfo(mem_ctx, guest_info);
1400         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1401 }
1402
1403 bool copy_current_user(struct current_user *dst, struct current_user *src)
1404 {
1405         gid_t *groups;
1406         NT_USER_TOKEN *nt_token;
1407
1408         groups = (gid_t *)memdup(src->ut.groups,
1409                                  sizeof(gid_t) * src->ut.ngroups);
1410         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1411                 return False;
1412         }
1413
1414         nt_token = dup_nt_token(NULL, src->nt_user_token);
1415         if (nt_token == NULL) {
1416                 SAFE_FREE(groups);
1417                 return False;
1418         }
1419
1420         dst->conn = src->conn;
1421         dst->vuid = src->vuid;
1422         dst->ut.uid = src->ut.uid;
1423         dst->ut.gid = src->ut.gid;
1424         dst->ut.ngroups = src->ut.ngroups;
1425         dst->ut.groups = groups;
1426         dst->nt_user_token = nt_token;
1427         return True;
1428 }
1429
1430 /***************************************************************************
1431  Purely internal function for make_server_info_info3
1432  Fill the sam account from getpwnam
1433 ***************************************************************************/
1434 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1435                                  const char *domain,
1436                                  const char *username,
1437                                  char **found_username,
1438                                  uid_t *uid, gid_t *gid,
1439                                  struct samu *account,
1440                                  bool *username_was_mapped)
1441 {
1442         NTSTATUS nt_status;
1443         fstring dom_user, lower_username;
1444         fstring real_username;
1445         struct passwd *passwd;
1446
1447         fstrcpy( lower_username, username );
1448         strlower_m( lower_username );
1449
1450         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1451                 lower_username);
1452
1453         /* Get the passwd struct.  Try to create the account is necessary. */
1454
1455         *username_was_mapped = map_username( dom_user );
1456
1457         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1458                 return NT_STATUS_NO_SUCH_USER;
1459
1460         *uid = passwd->pw_uid;
1461         *gid = passwd->pw_gid;
1462
1463         /* This is pointless -- there is no suport for differing 
1464            unix and windows names.  Make sure to always store the 
1465            one we actually looked up and succeeded. Have I mentioned
1466            why I hate the 'winbind use default domain' parameter?   
1467                                          --jerry              */
1468            
1469         *found_username = talloc_strdup( mem_ctx, real_username );
1470         
1471         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1472
1473         nt_status = samu_set_unix( account, passwd );
1474         
1475         TALLOC_FREE(passwd);
1476         
1477         return nt_status;
1478 }
1479
1480 /****************************************************************************
1481  Wrapper to allow the getpwnam() call to strip the domain name and 
1482  try again in case a local UNIX user is already there.  Also run through 
1483  the username if we fallback to the username only.
1484  ****************************************************************************/
1485  
1486 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1487                              fstring save_username, bool create )
1488 {
1489         struct passwd *pw = NULL;
1490         char *p;
1491         fstring username;
1492         
1493         /* we only save a copy of the username it has been mangled 
1494            by winbindd use default domain */
1495            
1496         save_username[0] = '\0';
1497            
1498         /* don't call map_username() here since it has to be done higher 
1499            up the stack so we don't call it mutliple times */
1500
1501         fstrcpy( username, domuser );
1502         
1503         p = strchr_m( username, *lp_winbind_separator() );
1504         
1505         /* code for a DOMAIN\user string */
1506         
1507         if ( p ) {
1508                 fstring strip_username;
1509
1510                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1511                 if ( pw ) {     
1512                         /* make sure we get the case of the username correct */
1513                         /* work around 'winbind use default domain = yes' */
1514
1515                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1516                                 char *domain;
1517                                 
1518                                 /* split the domain and username into 2 strings */
1519                                 *p = '\0';
1520                                 domain = username;
1521
1522                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1523                         }
1524                         else
1525                                 fstrcpy( save_username, pw->pw_name );
1526
1527                         /* whew -- done! */             
1528                         return pw;
1529                 }
1530
1531                 /* setup for lookup of just the username */
1532                 /* remember that p and username are overlapping memory */
1533
1534                 p++;
1535                 fstrcpy( strip_username, p );
1536                 fstrcpy( username, strip_username );
1537         }
1538         
1539         /* just lookup a plain username */
1540         
1541         pw = Get_Pwnam_alloc(mem_ctx, username);
1542                 
1543         /* Create local user if requested but only if winbindd
1544            is not running.  We need to protect against cases
1545            where winbindd is failing and then prematurely
1546            creating users in /etc/passwd */
1547         
1548         if ( !pw && create && !winbind_ping() ) {
1549                 /* Don't add a machine account. */
1550                 if (username[strlen(username)-1] == '$')
1551                         return NULL;
1552
1553                 smb_create_user(NULL, username, NULL);
1554                 pw = Get_Pwnam_alloc(mem_ctx, username);
1555         }
1556         
1557         /* one last check for a valid passwd struct */
1558         
1559         if ( pw )
1560                 fstrcpy( save_username, pw->pw_name );
1561
1562         return pw;
1563 }
1564
1565 /***************************************************************************
1566  Make a server_info struct from the info3 returned by a domain logon 
1567 ***************************************************************************/
1568
1569 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1570                                 const char *sent_nt_username,
1571                                 const char *domain,
1572                                 auth_serversupplied_info **server_info, 
1573                                 struct netr_SamInfo3 *info3)
1574 {
1575         char zeros[16];
1576
1577         NTSTATUS nt_status = NT_STATUS_OK;
1578         char *found_username = NULL;
1579         const char *nt_domain;
1580         const char *nt_username;
1581         struct samu *sam_account = NULL;
1582         DOM_SID user_sid;
1583         DOM_SID group_sid;
1584         bool username_was_mapped;
1585
1586         uid_t uid = (uid_t)-1;
1587         gid_t gid = (gid_t)-1;
1588
1589         auth_serversupplied_info *result;
1590
1591         /* 
1592            Here is where we should check the list of
1593            trusted domains, and verify that the SID 
1594            matches.
1595         */
1596
1597         sid_copy(&user_sid, info3->base.domain_sid);
1598         if (!sid_append_rid(&user_sid, info3->base.rid)) {
1599                 return NT_STATUS_INVALID_PARAMETER;
1600         }
1601         
1602         sid_copy(&group_sid, info3->base.domain_sid);
1603         if (!sid_append_rid(&group_sid, info3->base.primary_gid)) {
1604                 return NT_STATUS_INVALID_PARAMETER;
1605         }
1606
1607         nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1608         if (!nt_username) {
1609                 /* If the server didn't give us one, just use the one we sent
1610                  * them */
1611                 nt_username = sent_nt_username;
1612         }
1613
1614         nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1615         if (!nt_domain) {
1616                 /* If the server didn't give us one, just use the one we sent
1617                  * them */
1618                 nt_domain = domain;
1619         }
1620         
1621         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1622            add user script (2.2.x behavior).
1623
1624            We use the _unmapped_ username here in an attempt to provide
1625            consistent username mapping behavior between kerberos and NTLM[SSP]
1626            authentication in domain mode security.  I.E. Username mapping
1627            should be applied to the fully qualified username
1628            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1629            called map_username() unnecessarily in make_user_info_map() but
1630            that is how the current code is designed.  Making the change here
1631            is the least disruptive place.  -- jerry */
1632            
1633         if ( !(sam_account = samu_new( NULL )) ) {
1634                 return NT_STATUS_NO_MEMORY;
1635         }
1636
1637         /* this call will try to create the user if necessary */
1638
1639         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1640                                      &found_username, &uid, &gid, sam_account,
1641                                      &username_was_mapped);
1642
1643         
1644         /* if we still don't have a valid unix account check for 
1645           'map to guest = bad uid' */
1646           
1647         if (!NT_STATUS_IS_OK(nt_status)) {
1648                 TALLOC_FREE( sam_account );
1649                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1650                         make_server_info_guest(NULL, server_info);
1651                         return NT_STATUS_OK;
1652                 }
1653                 return nt_status;
1654         }
1655                 
1656         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1657                 TALLOC_FREE(sam_account);
1658                 return NT_STATUS_NO_MEMORY;
1659         }
1660
1661         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1662                 TALLOC_FREE(sam_account);
1663                 return NT_STATUS_NO_MEMORY;
1664         }
1665
1666         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1667                 TALLOC_FREE(sam_account);
1668                 return NT_STATUS_NO_MEMORY;
1669         }
1670
1671         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1672                 TALLOC_FREE(sam_account);
1673                 return NT_STATUS_UNSUCCESSFUL;
1674         }
1675
1676         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1677                 TALLOC_FREE(sam_account);
1678                 return NT_STATUS_UNSUCCESSFUL;
1679         }
1680
1681         if (!pdb_set_fullname(sam_account,
1682                               info3->base.full_name.string,
1683                               PDB_CHANGED)) {
1684                 TALLOC_FREE(sam_account);
1685                 return NT_STATUS_NO_MEMORY;
1686         }
1687
1688         if (!pdb_set_logon_script(sam_account,
1689                                   info3->base.logon_script.string,
1690                                   PDB_CHANGED)) {
1691                 TALLOC_FREE(sam_account);
1692                 return NT_STATUS_NO_MEMORY;
1693         }
1694
1695         if (!pdb_set_profile_path(sam_account,
1696                                   info3->base.profile_path.string,
1697                                   PDB_CHANGED)) {
1698                 TALLOC_FREE(sam_account);
1699                 return NT_STATUS_NO_MEMORY;
1700         }
1701
1702         if (!pdb_set_homedir(sam_account,
1703                              info3->base.home_directory.string,
1704                              PDB_CHANGED)) {
1705                 TALLOC_FREE(sam_account);
1706                 return NT_STATUS_NO_MEMORY;
1707         }
1708
1709         if (!pdb_set_dir_drive(sam_account,
1710                                info3->base.home_drive.string,
1711                                PDB_CHANGED)) {
1712                 TALLOC_FREE(sam_account);
1713                 return NT_STATUS_NO_MEMORY;
1714         }
1715
1716         if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {
1717                 TALLOC_FREE(sam_account);
1718                 return NT_STATUS_NO_MEMORY;
1719         }
1720
1721         if (!pdb_set_pass_last_set_time(
1722                     sam_account,
1723                     nt_time_to_unix(info3->base.last_password_change),
1724                     PDB_CHANGED)) {
1725                 TALLOC_FREE(sam_account);
1726                 return NT_STATUS_NO_MEMORY;
1727         }
1728
1729         if (!pdb_set_pass_can_change_time(
1730                     sam_account,
1731                     nt_time_to_unix(info3->base.allow_password_change),
1732                     PDB_CHANGED)) {
1733                 TALLOC_FREE(sam_account);
1734                 return NT_STATUS_NO_MEMORY;
1735         }
1736
1737         if (!pdb_set_pass_must_change_time(
1738                     sam_account,
1739                     nt_time_to_unix(info3->base.force_password_change),
1740                     PDB_CHANGED)) {
1741                 TALLOC_FREE(sam_account);
1742                 return NT_STATUS_NO_MEMORY;
1743         }
1744
1745         result = make_server_info(NULL);
1746         if (result == NULL) {
1747                 DEBUG(4, ("make_server_info failed!\n"));
1748                 TALLOC_FREE(sam_account);
1749                 return NT_STATUS_NO_MEMORY;
1750         }
1751
1752         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1753            valid struct samu) */
1754                    
1755         result->sam_account = sam_account;
1756         result->unix_name = talloc_strdup(result, found_username);
1757
1758         result->sanitized_username = sanitize_username(result,
1759                                                        result->unix_name);
1760         if (result->sanitized_username == NULL) {
1761                 TALLOC_FREE(result);
1762                 return NT_STATUS_NO_MEMORY;
1763         }
1764
1765         /* Fill in the unix info we found on the way */
1766
1767         result->utok.uid = uid;
1768         result->utok.gid = gid;
1769
1770         /* Create a 'combined' list of all SIDs we might want in the SD */
1771
1772         result->num_sids = 0;
1773         result->sids = NULL;
1774
1775         nt_status = sid_array_from_info3(result, info3,
1776                                          &result->sids,
1777                                          &result->num_sids,
1778                                          false, false);
1779         if (!NT_STATUS_IS_OK(nt_status)) {
1780                 TALLOC_FREE(result);
1781                 return nt_status;
1782         }
1783
1784         /* Ensure the primary group sid is at position 0. */
1785         sort_sid_array_for_smbd(result, &group_sid);
1786
1787         result->login_server = talloc_strdup(result,
1788                                              info3->base.logon_server.string);
1789
1790         /* ensure we are never given NULL session keys */
1791
1792         ZERO_STRUCT(zeros);
1793
1794         if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1795                 result->user_session_key = data_blob_null;
1796         } else {
1797                 result->user_session_key = data_blob_talloc(
1798                         result, info3->base.key.key,
1799                         sizeof(info3->base.key.key));
1800         }
1801
1802         if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1803                 result->lm_session_key = data_blob_null;
1804         } else {
1805                 result->lm_session_key = data_blob_talloc(
1806                         result, info3->base.LMSessKey.key,
1807                         sizeof(info3->base.LMSessKey.key));
1808         }
1809
1810         result->nss_token |= username_was_mapped;
1811
1812         *server_info = result;
1813
1814         return NT_STATUS_OK;
1815 }
1816
1817 /*****************************************************************************
1818  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1819 ******************************************************************************/
1820
1821 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1822                                           const char *sent_nt_username,
1823                                           const char *domain,
1824                                           const struct wbcAuthUserInfo *info,
1825                                           auth_serversupplied_info **server_info)
1826 {
1827         char zeros[16];
1828
1829         NTSTATUS nt_status = NT_STATUS_OK;
1830         char *found_username = NULL;
1831         const char *nt_domain;
1832         const char *nt_username;
1833         struct samu *sam_account = NULL;
1834         DOM_SID user_sid;
1835         DOM_SID group_sid;
1836         bool username_was_mapped;
1837         uint32_t i;
1838
1839         uid_t uid = (uid_t)-1;
1840         gid_t gid = (gid_t)-1;
1841
1842         auth_serversupplied_info *result;
1843
1844         result = make_server_info(NULL);
1845         if (result == NULL) {
1846                 DEBUG(4, ("make_server_info failed!\n"));
1847                 return NT_STATUS_NO_MEMORY;
1848         }
1849
1850         /*
1851            Here is where we should check the list of
1852            trusted domains, and verify that the SID
1853            matches.
1854         */
1855
1856         memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
1857         memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
1858
1859         if (info->account_name) {
1860                 nt_username = talloc_strdup(result, info->account_name);
1861         } else {
1862                 /* If the server didn't give us one, just use the one we sent
1863                  * them */
1864                 nt_username = talloc_strdup(result, sent_nt_username);
1865         }
1866         if (!nt_username) {
1867                 TALLOC_FREE(result);
1868                 return NT_STATUS_NO_MEMORY;
1869         }
1870
1871         if (info->domain_name) {
1872                 nt_domain = talloc_strdup(result, info->domain_name);
1873         } else {
1874                 /* If the server didn't give us one, just use the one we sent
1875                  * them */
1876                 nt_domain = talloc_strdup(result, domain);
1877         }
1878         if (!nt_domain) {
1879                 TALLOC_FREE(result);
1880                 return NT_STATUS_NO_MEMORY;
1881         }
1882
1883         /* try to fill the SAM account..  If getpwnam() fails, then try the
1884            add user script (2.2.x behavior).
1885
1886            We use the _unmapped_ username here in an attempt to provide
1887            consistent username mapping behavior between kerberos and NTLM[SSP]
1888            authentication in domain mode security.  I.E. Username mapping
1889            should be applied to the fully qualified username
1890            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1891            called map_username() unnecessarily in make_user_info_map() but
1892            that is how the current code is designed.  Making the change here
1893            is the least disruptive place.  -- jerry */
1894
1895         if ( !(sam_account = samu_new( result )) ) {
1896                 TALLOC_FREE(result);
1897                 return NT_STATUS_NO_MEMORY;
1898         }
1899
1900         /* this call will try to create the user if necessary */
1901
1902         nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
1903                                      &found_username, &uid, &gid, sam_account,
1904                                      &username_was_mapped);
1905
1906         /* if we still don't have a valid unix account check for
1907           'map to guest = bad uid' */
1908
1909         if (!NT_STATUS_IS_OK(nt_status)) {
1910                 TALLOC_FREE( result );
1911                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1912                         make_server_info_guest(NULL, server_info);
1913                         return NT_STATUS_OK;
1914                 }
1915                 return nt_status;
1916         }
1917
1918         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1919                 TALLOC_FREE(result);
1920                 return NT_STATUS_NO_MEMORY;
1921         }
1922
1923         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1924                 TALLOC_FREE(result);
1925                 return NT_STATUS_NO_MEMORY;
1926         }
1927
1928         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1929                 TALLOC_FREE(result);
1930                 return NT_STATUS_NO_MEMORY;
1931         }
1932
1933         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1934                 TALLOC_FREE(result);
1935                 return NT_STATUS_UNSUCCESSFUL;
1936         }
1937
1938         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1939                 TALLOC_FREE(result);
1940                 return NT_STATUS_UNSUCCESSFUL;
1941         }
1942
1943         if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
1944                 TALLOC_FREE(result);
1945                 return NT_STATUS_NO_MEMORY;
1946         }
1947
1948         if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
1949                 TALLOC_FREE(result);
1950                 return NT_STATUS_NO_MEMORY;
1951         }
1952
1953         if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
1954                 TALLOC_FREE(result);
1955                 return NT_STATUS_NO_MEMORY;
1956         }
1957
1958         if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
1959                 TALLOC_FREE(result);
1960                 return NT_STATUS_NO_MEMORY;
1961         }
1962
1963         if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
1964                 TALLOC_FREE(result);
1965                 return NT_STATUS_NO_MEMORY;
1966         }
1967
1968         if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
1969                 TALLOC_FREE(result);
1970                 return NT_STATUS_NO_MEMORY;
1971         }
1972
1973         if (!pdb_set_pass_last_set_time(
1974                     sam_account,
1975                     nt_time_to_unix(info->pass_last_set_time),
1976                     PDB_CHANGED)) {
1977                 TALLOC_FREE(result);
1978                 return NT_STATUS_NO_MEMORY;
1979         }
1980
1981         if (!pdb_set_pass_can_change_time(
1982                     sam_account,
1983                     nt_time_to_unix(info->pass_can_change_time),
1984                     PDB_CHANGED)) {
1985                 TALLOC_FREE(result);
1986                 return NT_STATUS_NO_MEMORY;
1987         }
1988
1989         if (!pdb_set_pass_must_change_time(
1990                     sam_account,
1991                     nt_time_to_unix(info->pass_must_change_time),
1992                     PDB_CHANGED)) {
1993                 TALLOC_FREE(result);
1994                 return NT_STATUS_NO_MEMORY;
1995         }
1996
1997         /* save this here to _net_sam_logon() doesn't fail (it assumes a
1998            valid struct samu) */
1999
2000         result->sam_account = sam_account;
2001         result->unix_name = talloc_strdup(result, found_username);
2002
2003         result->sanitized_username = sanitize_username(result,
2004                                                        result->unix_name);
2005         result->login_server = talloc_strdup(result, info->logon_server);
2006
2007         if ((result->unix_name == NULL)
2008             || (result->sanitized_username == NULL)
2009             || (result->login_server == NULL)) {
2010                 TALLOC_FREE(result);
2011                 return NT_STATUS_NO_MEMORY;
2012         }
2013
2014         /* Fill in the unix info we found on the way */
2015
2016         result->utok.uid = uid;
2017         result->utok.gid = gid;
2018
2019         /* Create a 'combined' list of all SIDs we might want in the SD */
2020
2021         result->num_sids = info->num_sids - 2;
2022         result->sids = talloc_array(result, DOM_SID, result->num_sids);
2023         if (result->sids == NULL) {
2024                 TALLOC_FREE(result);
2025                 return NT_STATUS_NO_MEMORY;
2026         }
2027
2028         for (i=0; i < result->num_sids; i++) {
2029                 memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
2030         }
2031
2032         /* Ensure the primary group sid is at position 0. */
2033         sort_sid_array_for_smbd(result, &group_sid);
2034
2035         /* ensure we are never given NULL session keys */
2036
2037         ZERO_STRUCT(zeros);
2038
2039         if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
2040                 result->user_session_key = data_blob_null;
2041         } else {
2042                 result->user_session_key = data_blob_talloc(
2043                         result, info->user_session_key,
2044                         sizeof(info->user_session_key));
2045         }
2046
2047         if (memcmp(info->lm_session_key, zeros, 8) == 0) {
2048                 result->lm_session_key = data_blob_null;
2049         } else {
2050                 result->lm_session_key = data_blob_talloc(
2051                         result, info->lm_session_key,
2052                         sizeof(info->lm_session_key));
2053         }
2054
2055         result->nss_token |= username_was_mapped;
2056
2057         *server_info = result;
2058
2059         return NT_STATUS_OK;
2060 }
2061
2062 /***************************************************************************
2063  Free a user_info struct
2064 ***************************************************************************/
2065
2066 void free_user_info(auth_usersupplied_info **user_info)
2067 {
2068         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
2069         if (*user_info != NULL) {
2070                 if ((*user_info)->smb_name) {
2071                         DEBUG(10,("structure was created for %s\n",
2072                                   (*user_info)->smb_name));
2073                 }
2074                 SAFE_FREE((*user_info)->smb_name);
2075                 SAFE_FREE((*user_info)->internal_username);
2076                 SAFE_FREE((*user_info)->client_domain);
2077                 SAFE_FREE((*user_info)->domain);
2078                 SAFE_FREE((*user_info)->wksta_name);
2079                 data_blob_free(&(*user_info)->lm_resp);
2080                 data_blob_free(&(*user_info)->nt_resp);
2081                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
2082                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
2083                 data_blob_clear_free(&(*user_info)->plaintext_password);
2084                 ZERO_STRUCT(**user_info);
2085         }
2086         SAFE_FREE(*user_info);
2087 }
2088
2089 /***************************************************************************
2090  Make an auth_methods struct
2091 ***************************************************************************/
2092
2093 bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
2094 {
2095         if (!auth_context) {
2096                 smb_panic("no auth_context supplied to "
2097                           "make_auth_methods()!\n");
2098         }
2099
2100         if (!auth_method) {
2101                 smb_panic("make_auth_methods: pointer to auth_method pointer "
2102                           "is NULL!\n");
2103         }
2104
2105         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
2106         if (!*auth_method) {
2107                 DEBUG(0,("make_auth_method: malloc failed!\n"));
2108                 return False;
2109         }
2110         ZERO_STRUCTP(*auth_method);
2111         
2112         return True;
2113 }
2114
2115 /**
2116  * Verify whether or not given domain is trusted.
2117  *
2118  * @param domain_name name of the domain to be verified
2119  * @return true if domain is one of the trusted once or
2120  *         false if otherwise
2121  **/
2122
2123 bool is_trusted_domain(const char* dom_name)
2124 {
2125         DOM_SID trustdom_sid;
2126         bool ret;
2127
2128         /* no trusted domains for a standalone server */
2129
2130         if ( lp_server_role() == ROLE_STANDALONE )
2131                 return False;
2132
2133         /* if we are a DC, then check for a direct trust relationships */
2134
2135         if ( IS_DC ) {
2136                 become_root();
2137                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2138                           "[%s]\n", dom_name ));
2139                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2140                 unbecome_root();
2141                 if (ret)
2142                         return True;
2143         }
2144         else {
2145                 wbcErr result;
2146
2147                 /* If winbind is around, ask it */
2148
2149                 result = wb_is_trusted_domain(dom_name);
2150
2151                 if (result == WBC_ERR_SUCCESS) {
2152                         return True;
2153                 }
2154
2155                 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
2156                         /* winbind could not find the domain */
2157                         return False;
2158                 }
2159
2160                 /* The only other possible result is that winbind is not up
2161                    and running. We need to update the trustdom_cache
2162                    ourselves */
2163                 
2164                 update_trustdom_cache();
2165         }
2166
2167         /* now the trustdom cache should be available a DC could still
2168          * have a transitive trust so fall back to the cache of trusted
2169          * domains (like a domain member would use  */
2170
2171         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
2172                 return True;
2173         }
2174
2175         return False;
2176 }
2177