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