Fix a typo
[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->was_mapped)) {
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
1111         if ( !(sampass = samu_new( NULL )) ) {
1112                 return NT_STATUS_NO_MEMORY;
1113         }
1114
1115         sid_copy(&guest_sid, get_global_sam_sid());
1116         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1117
1118         become_root();
1119         ret = pdb_getsampwsid(sampass, &guest_sid);
1120         unbecome_root();
1121
1122         if (!ret) {
1123                 TALLOC_FREE(sampass);
1124                 return NT_STATUS_NO_SUCH_USER;
1125         }
1126
1127         status = make_server_info_sam(server_info, sampass);
1128         if (!NT_STATUS_IS_OK(status)) {
1129                 TALLOC_FREE(sampass);
1130                 return status;
1131         }
1132         
1133         (*server_info)->guest = True;
1134
1135         status = create_local_token(*server_info);
1136         if (!NT_STATUS_IS_OK(status)) {
1137                 DEBUG(10, ("create_local_token failed: %s\n",
1138                            nt_errstr(status)));
1139                 return status;
1140         }
1141
1142         /* annoying, but the Guest really does have a session key, and it is
1143            all zeros! */
1144         ZERO_STRUCT(zeros);
1145         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1146         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1147
1148         return NT_STATUS_OK;
1149 }
1150
1151 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1152 {
1153         auth_serversupplied_info *dst;
1154
1155         dst = make_server_info(NULL);
1156         if (dst == NULL) {
1157                 return NULL;
1158         }
1159
1160         dst->guest = src->guest;
1161         dst->uid = src->uid;
1162         dst->gid = src->gid;
1163         dst->n_groups = src->n_groups;
1164         if (src->n_groups != 0) {
1165                 dst->groups = (gid_t *)TALLOC_MEMDUP(
1166                         dst, src->groups, sizeof(gid_t)*dst->n_groups);
1167         } else {
1168                 dst->groups = NULL;
1169         }
1170
1171         if (src->ptok) {
1172                 dst->ptok = dup_nt_token(dst, src->ptok);
1173                 if (!dst->ptok) {
1174                         TALLOC_FREE(dst);
1175                         return NULL;
1176                 }
1177         }
1178         
1179         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1180                                                 src->user_session_key.length);
1181
1182         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1183                                                 src->lm_session_key.length);
1184
1185         dst->sam_account = samu_new(NULL);
1186         if (!dst->sam_account) {
1187                 TALLOC_FREE(dst);
1188                 return NULL;
1189         }
1190
1191         if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1192                 TALLOC_FREE(dst);
1193                 return NULL;
1194         }
1195         
1196         dst->pam_handle = NULL;
1197         dst->unix_name = talloc_strdup(dst, src->unix_name);
1198         if (!dst->unix_name) {
1199                 TALLOC_FREE(dst);
1200                 return NULL;
1201         }
1202
1203         return dst;
1204 }
1205
1206 static auth_serversupplied_info *guest_info = NULL;
1207
1208 bool init_guest_info(void)
1209 {
1210         if (guest_info != NULL)
1211                 return True;
1212
1213         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1214 }
1215
1216 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1217 {
1218         *server_info = copy_serverinfo(guest_info);
1219         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1220 }
1221
1222 bool copy_current_user(struct current_user *dst, struct current_user *src)
1223 {
1224         gid_t *groups;
1225         NT_USER_TOKEN *nt_token;
1226
1227         groups = (gid_t *)memdup(src->ut.groups,
1228                                  sizeof(gid_t) * src->ut.ngroups);
1229         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1230                 return False;
1231         }
1232
1233         nt_token = dup_nt_token(NULL, src->nt_user_token);
1234         if (nt_token == NULL) {
1235                 SAFE_FREE(groups);
1236                 return False;
1237         }
1238
1239         dst->conn = src->conn;
1240         dst->vuid = src->vuid;
1241         dst->ut.uid = src->ut.uid;
1242         dst->ut.gid = src->ut.gid;
1243         dst->ut.ngroups = src->ut.ngroups;
1244         dst->ut.groups = groups;
1245         dst->nt_user_token = nt_token;
1246         return True;
1247 }
1248
1249 /***************************************************************************
1250  Purely internal function for make_server_info_info3
1251  Fill the sam account from getpwnam
1252 ***************************************************************************/
1253 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1254                                  const char *domain,
1255                                  const char *username,
1256                                  char **found_username,
1257                                  uid_t *uid, gid_t *gid,
1258                                  struct samu *account,
1259                                  bool *username_was_mapped)
1260 {
1261         NTSTATUS nt_status;
1262         fstring dom_user, lower_username;
1263         fstring real_username;
1264         struct passwd *passwd;
1265
1266         fstrcpy( lower_username, username );
1267         strlower_m( lower_username );
1268
1269         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1270                 lower_username);
1271
1272         /* Get the passwd struct.  Try to create the account is necessary. */
1273
1274         *username_was_mapped = map_username( dom_user );
1275
1276         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1277                 return NT_STATUS_NO_SUCH_USER;
1278
1279         *uid = passwd->pw_uid;
1280         *gid = passwd->pw_gid;
1281
1282         /* This is pointless -- there is no suport for differing 
1283            unix and windows names.  Make sure to always store the 
1284            one we actually looked up and succeeded. Have I mentioned
1285            why I hate the 'winbind use default domain' parameter?   
1286                                          --jerry              */
1287            
1288         *found_username = talloc_strdup( mem_ctx, real_username );
1289         
1290         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1291
1292         nt_status = samu_set_unix( account, passwd );
1293         
1294         TALLOC_FREE(passwd);
1295         
1296         return nt_status;
1297 }
1298
1299 /****************************************************************************
1300  Wrapper to allow the getpwnam() call to strip the domain name and 
1301  try again in case a local UNIX user is already there.  Also run through 
1302  the username if we fallback to the username only.
1303  ****************************************************************************/
1304  
1305 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1306                              fstring save_username, bool create )
1307 {
1308         struct passwd *pw = NULL;
1309         char *p;
1310         fstring username;
1311         
1312         /* we only save a copy of the username it has been mangled 
1313            by winbindd use default domain */
1314            
1315         save_username[0] = '\0';
1316            
1317         /* don't call map_username() here since it has to be done higher 
1318            up the stack so we don't call it mutliple times */
1319
1320         fstrcpy( username, domuser );
1321         
1322         p = strchr_m( username, *lp_winbind_separator() );
1323         
1324         /* code for a DOMAIN\user string */
1325         
1326         if ( p ) {
1327                 fstring strip_username;
1328
1329                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1330                 if ( pw ) {     
1331                         /* make sure we get the case of the username correct */
1332                         /* work around 'winbind use default domain = yes' */
1333
1334                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1335                                 char *domain;
1336                                 
1337                                 /* split the domain and username into 2 strings */
1338                                 *p = '\0';
1339                                 domain = username;
1340
1341                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1342                         }
1343                         else
1344                                 fstrcpy( save_username, pw->pw_name );
1345
1346                         /* whew -- done! */             
1347                         return pw;
1348                 }
1349
1350                 /* setup for lookup of just the username */
1351                 /* remember that p and username are overlapping memory */
1352
1353                 p++;
1354                 fstrcpy( strip_username, p );
1355                 fstrcpy( username, strip_username );
1356         }
1357         
1358         /* just lookup a plain username */
1359         
1360         pw = Get_Pwnam_alloc(mem_ctx, username);
1361                 
1362         /* Create local user if requested but only if winbindd
1363            is not running.  We need to protect against cases
1364            where winbindd is failing and then prematurely
1365            creating users in /etc/passwd */
1366         
1367         if ( !pw && create && !winbind_ping() ) {
1368                 /* Don't add a machine account. */
1369                 if (username[strlen(username)-1] == '$')
1370                         return NULL;
1371
1372                 smb_create_user(NULL, username, NULL);
1373                 pw = Get_Pwnam_alloc(mem_ctx, username);
1374         }
1375         
1376         /* one last check for a valid passwd struct */
1377         
1378         if ( pw )
1379                 fstrcpy( save_username, pw->pw_name );
1380
1381         return pw;
1382 }
1383
1384 /***************************************************************************
1385  Make a server_info struct from the info3 returned by a domain logon 
1386 ***************************************************************************/
1387
1388 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1389                                 const char *sent_nt_username,
1390                                 const char *domain,
1391                                 auth_serversupplied_info **server_info, 
1392                                 struct netr_SamInfo3 *info3)
1393 {
1394         char zeros[16];
1395
1396         NTSTATUS nt_status = NT_STATUS_OK;
1397         char *found_username = NULL;
1398         const char *nt_domain;
1399         const char *nt_username;
1400         struct samu *sam_account = NULL;
1401         DOM_SID user_sid;
1402         DOM_SID group_sid;
1403         bool username_was_mapped;
1404
1405         uid_t uid = (uid_t)-1;
1406         gid_t gid = (gid_t)-1;
1407
1408         auth_serversupplied_info *result;
1409
1410         /* 
1411            Here is where we should check the list of
1412            trusted domains, and verify that the SID 
1413            matches.
1414         */
1415
1416         sid_copy(&user_sid, info3->base.domain_sid);
1417         if (!sid_append_rid(&user_sid, info3->base.rid)) {
1418                 return NT_STATUS_INVALID_PARAMETER;
1419         }
1420         
1421         sid_copy(&group_sid, info3->base.domain_sid);
1422         if (!sid_append_rid(&group_sid, info3->base.primary_gid)) {
1423                 return NT_STATUS_INVALID_PARAMETER;
1424         }
1425
1426         nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1427         if (!nt_username) {
1428                 /* If the server didn't give us one, just use the one we sent
1429                  * them */
1430                 nt_username = sent_nt_username;
1431         }
1432
1433         nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1434         if (!nt_domain) {
1435                 /* If the server didn't give us one, just use the one we sent
1436                  * them */
1437                 nt_domain = domain;
1438         }
1439         
1440         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1441            add user script (2.2.x behavior).
1442
1443            We use the _unmapped_ username here in an attempt to provide
1444            consistent username mapping behavior between kerberos and NTLM[SSP]
1445            authentication in domain mode security.  I.E. Username mapping
1446            should be applied to the fully qualified username
1447            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1448            called map_username() unnecessarily in make_user_info_map() but
1449            that is how the current code is designed.  Making the change here
1450            is the least disruptive place.  -- jerry */
1451            
1452         if ( !(sam_account = samu_new( NULL )) ) {
1453                 return NT_STATUS_NO_MEMORY;
1454         }
1455
1456         /* this call will try to create the user if necessary */
1457
1458         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1459                                      &found_username, &uid, &gid, sam_account,
1460                                      &username_was_mapped);
1461
1462         
1463         /* if we still don't have a valid unix account check for 
1464           'map to guest = bad uid' */
1465           
1466         if (!NT_STATUS_IS_OK(nt_status)) {
1467                 TALLOC_FREE( sam_account );
1468                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1469                         make_server_info_guest(server_info); 
1470                         return NT_STATUS_OK;
1471                 }
1472                 return nt_status;
1473         }
1474                 
1475         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1476                 TALLOC_FREE(sam_account);
1477                 return NT_STATUS_NO_MEMORY;
1478         }
1479
1480         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1481                 TALLOC_FREE(sam_account);
1482                 return NT_STATUS_NO_MEMORY;
1483         }
1484
1485         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1486                 TALLOC_FREE(sam_account);
1487                 return NT_STATUS_NO_MEMORY;
1488         }
1489
1490         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1491                 TALLOC_FREE(sam_account);
1492                 return NT_STATUS_UNSUCCESSFUL;
1493         }
1494
1495         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1496                 TALLOC_FREE(sam_account);
1497                 return NT_STATUS_UNSUCCESSFUL;
1498         }
1499
1500         if (!pdb_set_fullname(sam_account,
1501                               info3->base.full_name.string,
1502                               PDB_CHANGED)) {
1503                 TALLOC_FREE(sam_account);
1504                 return NT_STATUS_NO_MEMORY;
1505         }
1506
1507         if (!pdb_set_logon_script(sam_account,
1508                                   info3->base.logon_script.string,
1509                                   PDB_CHANGED)) {
1510                 TALLOC_FREE(sam_account);
1511                 return NT_STATUS_NO_MEMORY;
1512         }
1513
1514         if (!pdb_set_profile_path(sam_account,
1515                                   info3->base.profile_path.string,
1516                                   PDB_CHANGED)) {
1517                 TALLOC_FREE(sam_account);
1518                 return NT_STATUS_NO_MEMORY;
1519         }
1520
1521         if (!pdb_set_homedir(sam_account,
1522                              info3->base.home_directory.string,
1523                              PDB_CHANGED)) {
1524                 TALLOC_FREE(sam_account);
1525                 return NT_STATUS_NO_MEMORY;
1526         }
1527
1528         if (!pdb_set_dir_drive(sam_account,
1529                                info3->base.home_drive.string,
1530                                PDB_CHANGED)) {
1531                 TALLOC_FREE(sam_account);
1532                 return NT_STATUS_NO_MEMORY;
1533         }
1534
1535         if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {
1536                 TALLOC_FREE(sam_account);
1537                 return NT_STATUS_NO_MEMORY;
1538         }
1539
1540         if (!pdb_set_pass_last_set_time(
1541                     sam_account,
1542                     nt_time_to_unix(info3->base.last_password_change),
1543                     PDB_CHANGED)) {
1544                 TALLOC_FREE(sam_account);
1545                 return NT_STATUS_NO_MEMORY;
1546         }
1547
1548         if (!pdb_set_pass_can_change_time(
1549                     sam_account,
1550                     nt_time_to_unix(info3->base.allow_password_change),
1551                     PDB_CHANGED)) {
1552                 TALLOC_FREE(sam_account);
1553                 return NT_STATUS_NO_MEMORY;
1554         }
1555
1556         if (!pdb_set_pass_must_change_time(
1557                     sam_account,
1558                     nt_time_to_unix(info3->base.force_password_change),
1559                     PDB_CHANGED)) {
1560                 TALLOC_FREE(sam_account);
1561                 return NT_STATUS_NO_MEMORY;
1562         }
1563
1564         result = make_server_info(NULL);
1565         if (result == NULL) {
1566                 DEBUG(4, ("make_server_info failed!\n"));
1567                 TALLOC_FREE(sam_account);
1568                 return NT_STATUS_NO_MEMORY;
1569         }
1570
1571         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1572            valid struct samu) */
1573                    
1574         result->sam_account = sam_account;
1575         result->unix_name = talloc_strdup(result, found_username);
1576
1577         /* Fill in the unix info we found on the way */
1578
1579         result->uid = uid;
1580         result->gid = gid;
1581
1582         /* Create a 'combined' list of all SIDs we might want in the SD */
1583
1584         result->num_sids = 0;
1585         result->sids = NULL;
1586
1587         nt_status = sid_array_from_info3(result, info3,
1588                                          &result->sids,
1589                                          &result->num_sids,
1590                                          false, false);
1591         if (!NT_STATUS_IS_OK(nt_status)) {
1592                 TALLOC_FREE(result);
1593                 return nt_status;
1594         }
1595
1596         result->login_server = talloc_strdup(result,
1597                                              info3->base.logon_server.string);
1598
1599         /* ensure we are never given NULL session keys */
1600
1601         ZERO_STRUCT(zeros);
1602
1603         if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1604                 result->user_session_key = data_blob_null;
1605         } else {
1606                 result->user_session_key = data_blob_talloc(
1607                         result, info3->base.key.key,
1608                         sizeof(info3->base.key.key));
1609         }
1610
1611         if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1612                 result->lm_session_key = data_blob_null;
1613         } else {
1614                 result->lm_session_key = data_blob_talloc(
1615                         result, info3->base.LMSessKey.key,
1616                         sizeof(info3->base.LMSessKey.key));
1617         }
1618
1619         result->was_mapped = username_was_mapped;
1620
1621         *server_info = result;
1622
1623         return NT_STATUS_OK;
1624 }
1625
1626 /*****************************************************************************
1627  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1628 ******************************************************************************/
1629
1630 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1631                                           const char *sent_nt_username,
1632                                           const char *domain,
1633                                           const struct wbcAuthUserInfo *info,
1634                                           auth_serversupplied_info **server_info)
1635 {
1636         char zeros[16];
1637
1638         NTSTATUS nt_status = NT_STATUS_OK;
1639         char *found_username = NULL;
1640         const char *nt_domain;
1641         const char *nt_username;
1642         struct samu *sam_account = NULL;
1643         DOM_SID user_sid;
1644         DOM_SID group_sid;
1645         bool username_was_mapped;
1646         uint32_t i;
1647
1648         uid_t uid = (uid_t)-1;
1649         gid_t gid = (gid_t)-1;
1650
1651         auth_serversupplied_info *result;
1652
1653         result = make_server_info(NULL);
1654         if (result == NULL) {
1655                 DEBUG(4, ("make_server_info failed!\n"));
1656                 return NT_STATUS_NO_MEMORY;
1657         }
1658
1659         /*
1660            Here is where we should check the list of
1661            trusted domains, and verify that the SID
1662            matches.
1663         */
1664
1665         memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
1666         memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
1667
1668         if (info->account_name) {
1669                 nt_username = talloc_strdup(result, info->account_name);
1670         } else {
1671                 /* If the server didn't give us one, just use the one we sent
1672                  * them */
1673                 nt_username = talloc_strdup(result, sent_nt_username);
1674         }
1675         if (!nt_username) {
1676                 TALLOC_FREE(result);
1677                 return NT_STATUS_NO_MEMORY;
1678         }
1679
1680         if (info->domain_name) {
1681                 nt_domain = talloc_strdup(result, info->domain_name);
1682         } else {
1683                 /* If the server didn't give us one, just use the one we sent
1684                  * them */
1685                 nt_domain = talloc_strdup(result, domain);
1686         }
1687         if (!nt_domain) {
1688                 TALLOC_FREE(result);
1689                 return NT_STATUS_NO_MEMORY;
1690         }
1691
1692         /* try to fill the SAM account..  If getpwnam() fails, then try the
1693            add user script (2.2.x behavior).
1694
1695            We use the _unmapped_ username here in an attempt to provide
1696            consistent username mapping behavior between kerberos and NTLM[SSP]
1697            authentication in domain mode security.  I.E. Username mapping
1698            should be applied to the fully qualified username
1699            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1700            called map_username() unnecessarily in make_user_info_map() but
1701            that is how the current code is designed.  Making the change here
1702            is the least disruptive place.  -- jerry */
1703
1704         if ( !(sam_account = samu_new( result )) ) {
1705                 TALLOC_FREE(result);
1706                 return NT_STATUS_NO_MEMORY;
1707         }
1708
1709         /* this call will try to create the user if necessary */
1710
1711         nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
1712                                      &found_username, &uid, &gid, sam_account,
1713                                      &username_was_mapped);
1714
1715         /* if we still don't have a valid unix account check for
1716           'map to guest = bad uid' */
1717
1718         if (!NT_STATUS_IS_OK(nt_status)) {
1719                 TALLOC_FREE( result );
1720                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1721                         make_server_info_guest(server_info);
1722                         return NT_STATUS_OK;
1723                 }
1724                 return nt_status;
1725         }
1726
1727         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1728                 TALLOC_FREE(result);
1729                 return NT_STATUS_NO_MEMORY;
1730         }
1731
1732         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1733                 TALLOC_FREE(result);
1734                 return NT_STATUS_NO_MEMORY;
1735         }
1736
1737         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1738                 TALLOC_FREE(result);
1739                 return NT_STATUS_NO_MEMORY;
1740         }
1741
1742         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1743                 TALLOC_FREE(result);
1744                 return NT_STATUS_UNSUCCESSFUL;
1745         }
1746
1747         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1748                 TALLOC_FREE(result);
1749                 return NT_STATUS_UNSUCCESSFUL;
1750         }
1751
1752         if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
1753                 TALLOC_FREE(result);
1754                 return NT_STATUS_NO_MEMORY;
1755         }
1756
1757         if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
1758                 TALLOC_FREE(result);
1759                 return NT_STATUS_NO_MEMORY;
1760         }
1761
1762         if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
1763                 TALLOC_FREE(result);
1764                 return NT_STATUS_NO_MEMORY;
1765         }
1766
1767         if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
1768                 TALLOC_FREE(result);
1769                 return NT_STATUS_NO_MEMORY;
1770         }
1771
1772         if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
1773                 TALLOC_FREE(result);
1774                 return NT_STATUS_NO_MEMORY;
1775         }
1776
1777         if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
1778                 TALLOC_FREE(result);
1779                 return NT_STATUS_NO_MEMORY;
1780         }
1781
1782         if (!pdb_set_pass_last_set_time(
1783                     sam_account,
1784                     nt_time_to_unix(info->pass_last_set_time),
1785                     PDB_CHANGED)) {
1786                 TALLOC_FREE(result);
1787                 return NT_STATUS_NO_MEMORY;
1788         }
1789
1790         if (!pdb_set_pass_can_change_time(
1791                     sam_account,
1792                     nt_time_to_unix(info->pass_can_change_time),
1793                     PDB_CHANGED)) {
1794                 TALLOC_FREE(result);
1795                 return NT_STATUS_NO_MEMORY;
1796         }
1797
1798         if (!pdb_set_pass_must_change_time(
1799                     sam_account,
1800                     nt_time_to_unix(info->pass_must_change_time),
1801                     PDB_CHANGED)) {
1802                 TALLOC_FREE(result);
1803                 return NT_STATUS_NO_MEMORY;
1804         }
1805
1806         /* save this here to _net_sam_logon() doesn't fail (it assumes a
1807            valid struct samu) */
1808
1809         result->sam_account = sam_account;
1810         result->unix_name = talloc_strdup(result, found_username);
1811
1812         result->login_server = talloc_strdup(result, info->logon_server);
1813
1814         /* Fill in the unix info we found on the way */
1815
1816         result->uid = uid;
1817         result->gid = gid;
1818
1819         /* Create a 'combined' list of all SIDs we might want in the SD */
1820
1821         result->num_sids = info->num_sids - 2;
1822         result->sids = talloc_array(result, DOM_SID, result->num_sids);
1823         if (result->sids == NULL) {
1824                 TALLOC_FREE(result);
1825                 return NT_STATUS_NO_MEMORY;
1826         }
1827
1828         for (i=0; i < result->num_sids; i++) {
1829                 memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
1830         }
1831
1832         /* ensure we are never given NULL session keys */
1833
1834         ZERO_STRUCT(zeros);
1835
1836         if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
1837                 result->user_session_key = data_blob_null;
1838         } else {
1839                 result->user_session_key = data_blob_talloc(
1840                         result, info->user_session_key,
1841                         sizeof(info->user_session_key));
1842         }
1843
1844         if (memcmp(info->lm_session_key, zeros, 8) == 0) {
1845                 result->lm_session_key = data_blob_null;
1846         } else {
1847                 result->lm_session_key = data_blob_talloc(
1848                         result, info->lm_session_key,
1849                         sizeof(info->lm_session_key));
1850         }
1851
1852         result->was_mapped = username_was_mapped;
1853
1854         *server_info = result;
1855
1856         return NT_STATUS_OK;
1857 }
1858
1859 /***************************************************************************
1860  Free a user_info struct
1861 ***************************************************************************/
1862
1863 void free_user_info(auth_usersupplied_info **user_info)
1864 {
1865         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1866         if (*user_info != NULL) {
1867                 if ((*user_info)->smb_name) {
1868                         DEBUG(10,("structure was created for %s\n",
1869                                   (*user_info)->smb_name));
1870                 }
1871                 SAFE_FREE((*user_info)->smb_name);
1872                 SAFE_FREE((*user_info)->internal_username);
1873                 SAFE_FREE((*user_info)->client_domain);
1874                 SAFE_FREE((*user_info)->domain);
1875                 SAFE_FREE((*user_info)->wksta_name);
1876                 data_blob_free(&(*user_info)->lm_resp);
1877                 data_blob_free(&(*user_info)->nt_resp);
1878                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1879                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1880                 data_blob_clear_free(&(*user_info)->plaintext_password);
1881                 ZERO_STRUCT(**user_info);
1882         }
1883         SAFE_FREE(*user_info);
1884 }
1885
1886 /***************************************************************************
1887  Make an auth_methods struct
1888 ***************************************************************************/
1889
1890 bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
1891 {
1892         if (!auth_context) {
1893                 smb_panic("no auth_context supplied to "
1894                           "make_auth_methods()!\n");
1895         }
1896
1897         if (!auth_method) {
1898                 smb_panic("make_auth_methods: pointer to auth_method pointer "
1899                           "is NULL!\n");
1900         }
1901
1902         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1903         if (!*auth_method) {
1904                 DEBUG(0,("make_auth_method: malloc failed!\n"));
1905                 return False;
1906         }
1907         ZERO_STRUCTP(*auth_method);
1908         
1909         return True;
1910 }
1911
1912 /**
1913  * Verify whether or not given domain is trusted.
1914  *
1915  * @param domain_name name of the domain to be verified
1916  * @return true if domain is one of the trusted once or
1917  *         false if otherwise
1918  **/
1919
1920 bool is_trusted_domain(const char* dom_name)
1921 {
1922         DOM_SID trustdom_sid;
1923         bool ret;
1924
1925         /* no trusted domains for a standalone server */
1926
1927         if ( lp_server_role() == ROLE_STANDALONE )
1928                 return False;
1929
1930         /* if we are a DC, then check for a direct trust relationships */
1931
1932         if ( IS_DC ) {
1933                 become_root();
1934                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1935                           "[%s]\n", dom_name ));
1936                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1937                 unbecome_root();
1938                 if (ret)
1939                         return True;
1940         }
1941         else {
1942                 wbcErr result;
1943
1944                 /* If winbind is around, ask it */
1945
1946                 result = wb_is_trusted_domain(dom_name);
1947
1948                 if (result == WBC_ERR_SUCCESS) {
1949                         return True;
1950                 }
1951
1952                 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1953                         /* winbind could not find the domain */
1954                         return False;
1955                 }
1956
1957                 /* The only other possible result is that winbind is not up
1958                    and running. We need to update the trustdom_cache
1959                    ourselves */
1960                 
1961                 update_trustdom_cache();
1962         }
1963
1964         /* now the trustdom cache should be available a DC could still
1965          * have a transitive trust so fall back to the cache of trusted
1966          * domains (like a domain member would use  */
1967
1968         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1969                 return True;
1970         }
1971
1972         return False;
1973 }
1974