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