Remove pstring from auth/*
[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                 if (!add_sid_to_array_unique( result, &unix_group_sid,
553                                 &result->sids, &result->num_sids )) {
554                         result->sam_account = NULL; /* Don't free on error exit. */
555                         TALLOC_FREE(result);
556                         return NT_STATUS_NO_MEMORY;
557                 }
558         }
559
560         /* For now we throw away the gids and convert via sid_to_gid
561          * later. This needs fixing, but I'd like to get the code straight and
562          * simple first. */
563          
564         TALLOC_FREE(gids);
565
566         DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
567                  pdb_get_username(sampass), result->unix_name));
568
569         *server_info = result;
570
571         return NT_STATUS_OK;
572 }
573
574 static NTSTATUS log_nt_token(TALLOC_CTX *tmp_ctx, NT_USER_TOKEN *token)
575 {
576         char *command;
577         char *group_sidstr;
578         size_t i;
579
580         if ((lp_log_nt_token_command() == NULL) ||
581             (strlen(lp_log_nt_token_command()) == 0)) {
582                 return NT_STATUS_OK;
583         }
584
585         group_sidstr = talloc_strdup(tmp_ctx, "");
586         for (i=1; i<token->num_sids; i++) {
587                 group_sidstr = talloc_asprintf(
588                         tmp_ctx, "%s %s", group_sidstr,
589                         sid_string_static(&token->user_sids[i]));
590         }
591
592         command = talloc_string_sub(
593                 tmp_ctx, lp_log_nt_token_command(),
594                 "%s", sid_string_static(&token->user_sids[0]));
595         command = talloc_string_sub(tmp_ctx, command, "%t", group_sidstr);
596
597         if (command == NULL) {
598                 return NT_STATUS_NO_MEMORY;
599         }
600
601         DEBUG(8, ("running command: [%s]\n", command));
602         if (smbrun(command, NULL) != 0) {
603                 DEBUG(0, ("Could not log NT token\n"));
604                 return NT_STATUS_ACCESS_DENIED;
605         }
606
607         return NT_STATUS_OK;
608 }
609
610 /*
611  * Create the token to use from server_info->sam_account and
612  * server_info->sids (the info3/sam groups). Find the unix gids.
613  */
614
615 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
616 {
617         TALLOC_CTX *mem_ctx;
618         NTSTATUS status;
619         size_t i;
620         
621
622         mem_ctx = talloc_new(NULL);
623         if (mem_ctx == NULL) {
624                 DEBUG(0, ("talloc_new failed\n"));
625                 return NT_STATUS_NO_MEMORY;
626         }
627
628         /*
629          * If winbind is not around, we can not make much use of the SIDs the
630          * domain controller provided us with. Likewise if the user name was
631          * mapped to some local unix user.
632          */
633
634         if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
635             (server_info->was_mapped)) {
636                 status = create_token_from_username(server_info,
637                                                     server_info->unix_name,
638                                                     server_info->guest,
639                                                     &server_info->uid,
640                                                     &server_info->gid,
641                                                     &server_info->unix_name,
642                                                     &server_info->ptok);
643                 
644         } else {
645                 server_info->ptok = create_local_nt_token(
646                         server_info,
647                         pdb_get_user_sid(server_info->sam_account),
648                         server_info->guest,
649                         server_info->num_sids, server_info->sids);
650                 status = server_info->ptok ?
651                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
652         }
653
654         if (!NT_STATUS_IS_OK(status)) {
655                 TALLOC_FREE(mem_ctx);
656                 return status;
657         }
658         
659         /* Convert the SIDs to gids. */
660
661         server_info->n_groups = 0;
662         server_info->groups = NULL;
663
664         /* Start at index 1, where the groups start. */
665
666         for (i=1; i<server_info->ptok->num_sids; i++) {
667                 gid_t gid;
668                 DOM_SID *sid = &server_info->ptok->user_sids[i];
669
670                 if (!sid_to_gid(sid, &gid)) {
671                         DEBUG(10, ("Could not convert SID %s to gid, "
672                                    "ignoring it\n", sid_string_static(sid)));
673                         continue;
674                 }
675                 add_gid_to_array_unique(server_info, gid, &server_info->groups,
676                                         &server_info->n_groups);
677         }
678         
679         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
680
681         status = log_nt_token(mem_ctx, server_info->ptok);
682
683         TALLOC_FREE(mem_ctx);
684         return status;
685 }
686
687 /*
688  * Create an artificial NT token given just a username. (Initially indended
689  * for force user)
690  *
691  * We go through lookup_name() to avoid problems we had with 'winbind use
692  * default domain'.
693  *
694  * We have 3 cases:
695  *
696  * unmapped unix users: Go directly to nss to find the user's group.
697  *
698  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
699  *
700  * If the user is provided by winbind, the primary gid is set to "domain
701  * users" of the user's domain. For an explanation why this is necessary, see
702  * the thread starting at
703  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
704  */
705
706 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
707                                     bool is_guest,
708                                     uid_t *uid, gid_t *gid,
709                                     char **found_username,
710                                     struct nt_user_token **token)
711 {
712         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
713         TALLOC_CTX *tmp_ctx;
714         DOM_SID user_sid;
715         enum lsa_SidType type;
716         gid_t *gids;
717         DOM_SID *group_sids;
718         DOM_SID unix_group_sid;
719         size_t num_group_sids;
720         size_t num_gids;
721         size_t i;
722
723         tmp_ctx = talloc_new(NULL);
724         if (tmp_ctx == NULL) {
725                 DEBUG(0, ("talloc_new failed\n"));
726                 return NT_STATUS_NO_MEMORY;
727         }
728
729         if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
730                          NULL, NULL, &user_sid, &type)) {
731                 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
732                 goto done;
733         }
734
735         if (type != SID_NAME_USER) {
736                 DEBUG(1, ("%s is a %s, not a user\n", username,
737                           sid_type_lookup(type)));
738                 goto done;
739         }
740
741         if (!sid_to_uid(&user_sid, uid)) {
742                 DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
743                           username, sid_string_static(&user_sid)));
744                 goto done;
745         }
746
747         if (sid_check_is_in_our_domain(&user_sid)) {
748                 bool ret;
749
750                 /* This is a passdb user, so ask passdb */
751
752                 struct samu *sam_acct = NULL;
753
754                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
755                         result = NT_STATUS_NO_MEMORY;
756                         goto done;
757                 }
758
759                 become_root();
760                 ret = pdb_getsampwsid(sam_acct, &user_sid);
761                 unbecome_root();
762
763                 if (!ret) {
764                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
765                                   sid_string_static(&user_sid), username));
766                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
767                         goto unix_user;
768                 }
769
770                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
771                                                     &group_sids, &gids,
772                                                     &num_group_sids);
773                 if (!NT_STATUS_IS_OK(result)) {
774                         DEBUG(10, ("enum_group_memberships failed for %s\n",
775                                    username));
776                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
777                         goto unix_user;
778                 }
779
780                 /* see the smb_panic() in pdb_default_enum_group_memberships */
781                 SMB_ASSERT(num_group_sids > 0); 
782
783                 *gid = gids[0];
784
785                 /* Ensure we're returning the found_username on the right context. */
786                 *found_username = talloc_strdup(mem_ctx,
787                                                 pdb_get_username(sam_acct));
788
789         } else  if (sid_check_is_in_unix_users(&user_sid)) {
790
791                 /* This is a unix user not in passdb. We need to ask nss
792                  * directly, without consulting passdb */
793
794                 struct passwd *pass;
795
796                 /*
797                  * This goto target is used as a fallback for the passdb
798                  * case. The concrete bug report is when passdb gave us an
799                  * unmapped gid.
800                  */
801
802         unix_user:
803
804                 uid_to_unix_users_sid(*uid, &user_sid);
805
806                 pass = getpwuid_alloc(tmp_ctx, *uid);
807                 if (pass == NULL) {
808                         DEBUG(1, ("getpwuid(%d) for user %s failed\n",
809                                   *uid, username));
810                         goto done;
811                 }
812
813                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
814                                          &gids, &num_group_sids)) {
815                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
816                                   username));
817                         goto done;
818                 }
819
820                 if (num_group_sids) {
821                         group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
822                         if (group_sids == NULL) {
823                                 DEBUG(1, ("TALLOC_ARRAY failed\n"));
824                                 result = NT_STATUS_NO_MEMORY;
825                                 goto done;
826                         }
827                 } else {
828                         group_sids = NULL;
829                 }
830
831                 for (i=0; i<num_group_sids; i++) {
832                         gid_to_sid(&group_sids[i], gids[i]);
833                 }
834
835                 /* In getgroups_unix_user we always set the primary gid */
836                 SMB_ASSERT(num_group_sids > 0); 
837
838                 *gid = gids[0];
839
840                 /* Ensure we're returning the found_username on the right context. */
841                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
842         } else {
843
844                 /* This user is from winbind, force the primary gid to the
845                  * user's "domain users" group. Under certain circumstances
846                  * (user comes from NT4), this might be a loss of
847                  * information. But we can not rely on winbind getting the
848                  * correct info. AD might prohibit winbind looking up that
849                  * information. */
850
851                 uint32 dummy;
852
853                 num_group_sids = 1;
854                 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
855                 if (group_sids == NULL) {
856                         DEBUG(1, ("TALLOC_ARRAY failed\n"));
857                         result = NT_STATUS_NO_MEMORY;
858                         goto done;
859                 }
860
861                 sid_copy(&group_sids[0], &user_sid);
862                 sid_split_rid(&group_sids[0], &dummy);
863                 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
864
865                 if (!sid_to_gid(&group_sids[0], gid)) {
866                         DEBUG(1, ("sid_to_gid(%s) failed\n",
867                                   sid_string_static(&group_sids[0])));
868                         goto done;
869                 }
870
871                 gids = gid;
872
873                 /* Ensure we're returning the found_username on the right context. */
874                 *found_username = talloc_strdup(mem_ctx, username);
875         }
876
877         /* Add the "Unix Group" SID for each gid to catch mapped groups
878            and their Unix equivalent.  This is to solve the backwards
879            compatibility problem of 'valid users = +ntadmin' where
880            ntadmin has been paired with "Domain Admins" in the group
881            mapping table.  Otherwise smb.conf would need to be changed
882            to 'valid user = "Domain Admins"'.  --jerry */
883
884         num_gids = num_group_sids;
885         for ( i=0; i<num_gids; i++ ) {
886                 gid_t high, low;
887
888                 /* don't pickup anything managed by Winbind */
889
890                 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
891                         continue;
892
893                 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
894                         DEBUG(1,("create_token_from_username: Failed to create SID "
895                                 "for gid %d!\n", gids[i]));
896                         continue;
897                 }
898                 if (!add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
899                                 &group_sids, &num_group_sids )) {
900                         result = NT_STATUS_NO_MEMORY;
901                         goto done;
902                 }
903         }
904
905         /* Ensure we're creating the nt_token on the right context. */
906         *token = create_local_nt_token(mem_ctx, &user_sid,
907                                        is_guest, num_group_sids, group_sids);
908
909         if ((*token == NULL) || (*found_username == NULL)) {
910                 result = NT_STATUS_NO_MEMORY;
911                 goto done;
912         }
913
914         result = NT_STATUS_OK;
915  done:
916         TALLOC_FREE(tmp_ctx);
917         return result;
918 }
919
920 /***************************************************************************
921  Build upon create_token_from_username:
922
923  Expensive helper function to figure out whether a user given its name is
924  member of a particular group.
925 ***************************************************************************/
926
927 bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
928 {
929         NTSTATUS status;
930         uid_t uid;
931         gid_t gid;
932         char *found_username;
933         struct nt_user_token *token;
934         bool result;
935
936         TALLOC_CTX *mem_ctx;
937
938         mem_ctx = talloc_new(NULL);
939         if (mem_ctx == NULL) {
940                 DEBUG(0, ("talloc_new failed\n"));
941                 return False;
942         }
943
944         status = create_token_from_username(mem_ctx, username, False,
945                                             &uid, &gid, &found_username,
946                                             &token);
947
948         if (!NT_STATUS_IS_OK(status)) {
949                 DEBUG(10, ("could not create token for %s\n", username));
950                 return False;
951         }
952
953         result = nt_token_check_sid(group_sid, token);
954
955         TALLOC_FREE(mem_ctx);
956         return result;
957         
958 }
959
960 bool user_in_group(const char *username, const char *groupname)
961 {
962         TALLOC_CTX *mem_ctx;
963         DOM_SID group_sid;
964         bool ret;
965
966         mem_ctx = talloc_new(NULL);
967         if (mem_ctx == NULL) {
968                 DEBUG(0, ("talloc_new failed\n"));
969                 return False;
970         }
971
972         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
973                           NULL, NULL, &group_sid, NULL);
974         TALLOC_FREE(mem_ctx);
975
976         if (!ret) {
977                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
978                 return False;
979         }
980
981         return user_in_group_sid(username, &group_sid);
982 }
983
984
985 /***************************************************************************
986  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
987  to a struct samu
988 ***************************************************************************/
989
990 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
991                              char *unix_username,
992                              struct passwd *pwd)
993 {
994         NTSTATUS status;
995         struct samu *sampass = NULL;
996         gid_t *gids;
997         char *qualified_name = NULL;
998         TALLOC_CTX *mem_ctx = NULL;
999         DOM_SID u_sid;
1000         enum lsa_SidType type;
1001         auth_serversupplied_info *result;
1002         
1003         if ( !(sampass = samu_new( NULL )) ) {
1004                 return NT_STATUS_NO_MEMORY;
1005         }
1006         
1007         status = samu_set_unix( sampass, pwd );
1008         if (!NT_STATUS_IS_OK(status)) {
1009                 return status;
1010         }
1011
1012         result = make_server_info(NULL);
1013         if (result == NULL) {
1014                 TALLOC_FREE(sampass);
1015                 return NT_STATUS_NO_MEMORY;
1016         }
1017
1018         result->sam_account = sampass;
1019         result->unix_name = talloc_strdup(result, unix_username);
1020         result->uid = pwd->pw_uid;
1021         result->gid = pwd->pw_gid;
1022
1023         status = pdb_enum_group_memberships(result, sampass,
1024                                             &result->sids, &gids,
1025                                             &result->num_sids);
1026
1027         if (!NT_STATUS_IS_OK(status)) {
1028                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1029                            nt_errstr(status)));
1030                 TALLOC_FREE(result);
1031                 return status;
1032         }
1033
1034         /*
1035          * The SID returned in server_info->sam_account is based
1036          * on our SAM sid even though for a pure UNIX account this should
1037          * not be the case as it doesn't really exist in the SAM db.
1038          * This causes lookups on "[in]valid users" to fail as they
1039          * will lookup this name as a "Unix User" SID to check against
1040          * the user token. Fix this by adding the "Unix User"\unix_username
1041          * SID to the sid array. The correct fix should probably be
1042          * changing the server_info->sam_account user SID to be a
1043          * S-1-22 Unix SID, but this might break old configs where
1044          * plaintext passwords were used with no SAM backend.
1045          */
1046
1047         mem_ctx = talloc_init("make_server_info_pw_tmp");
1048         if (!mem_ctx) {
1049                 TALLOC_FREE(result);
1050                 return NT_STATUS_NO_MEMORY;
1051         }
1052
1053         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
1054                                         unix_users_domain_name(),
1055                                         unix_username );
1056         if (!qualified_name) {
1057                 TALLOC_FREE(result);
1058                 TALLOC_FREE(mem_ctx);
1059                 return NT_STATUS_NO_MEMORY;
1060         }
1061
1062         if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
1063                                                 NULL, NULL,
1064                                                 &u_sid, &type)) {
1065                 TALLOC_FREE(result);
1066                 TALLOC_FREE(mem_ctx);
1067                 return NT_STATUS_NO_SUCH_USER;
1068         }
1069
1070         TALLOC_FREE(mem_ctx);
1071
1072         if (type != SID_NAME_USER) {
1073                 TALLOC_FREE(result);
1074                 return NT_STATUS_NO_SUCH_USER;
1075         }
1076
1077         if (!add_sid_to_array_unique(result, &u_sid,
1078                                         &result->sids,
1079                                         &result->num_sids)) {
1080                 TALLOC_FREE(result);
1081                 return NT_STATUS_NO_MEMORY;
1082         }
1083
1084         /* For now we throw away the gids and convert via sid_to_gid
1085          * later. This needs fixing, but I'd like to get the code straight and
1086          * simple first. */
1087         TALLOC_FREE(gids);
1088
1089         *server_info = result;
1090
1091         return NT_STATUS_OK;
1092 }
1093
1094 /***************************************************************************
1095  Make (and fill) a user_info struct for a guest login.
1096  This *must* succeed for smbd to start. If there is no mapping entry for
1097  the guest gid, then create one.
1098 ***************************************************************************/
1099
1100 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1101 {
1102         NTSTATUS status;
1103         struct samu *sampass = NULL;
1104         DOM_SID guest_sid;
1105         bool ret;
1106         static const char zeros[16] = { 0, };
1107
1108         if ( !(sampass = samu_new( NULL )) ) {
1109                 return NT_STATUS_NO_MEMORY;
1110         }
1111
1112         sid_copy(&guest_sid, get_global_sam_sid());
1113         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1114
1115         become_root();
1116         ret = pdb_getsampwsid(sampass, &guest_sid);
1117         unbecome_root();
1118
1119         if (!ret) {
1120                 TALLOC_FREE(sampass);
1121                 return NT_STATUS_NO_SUCH_USER;
1122         }
1123
1124         status = make_server_info_sam(server_info, sampass);
1125         if (!NT_STATUS_IS_OK(status)) {
1126                 TALLOC_FREE(sampass);
1127                 return status;
1128         }
1129         
1130         (*server_info)->guest = True;
1131
1132         status = create_local_token(*server_info);
1133         if (!NT_STATUS_IS_OK(status)) {
1134                 DEBUG(10, ("create_local_token failed: %s\n",
1135                            nt_errstr(status)));
1136                 return status;
1137         }
1138
1139         /* annoying, but the Guest really does have a session key, and it is
1140            all zeros! */
1141         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1142         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1143
1144         return NT_STATUS_OK;
1145 }
1146
1147 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1148 {
1149         auth_serversupplied_info *dst;
1150
1151         dst = make_server_info(NULL);
1152         if (dst == NULL) {
1153                 return NULL;
1154         }
1155
1156         dst->guest = src->guest;
1157         dst->uid = src->uid;
1158         dst->gid = src->gid;
1159         dst->n_groups = src->n_groups;
1160         if (src->n_groups != 0) {
1161                 dst->groups = (gid_t *)TALLOC_MEMDUP(
1162                         dst, src->groups, sizeof(gid_t)*dst->n_groups);
1163         } else {
1164                 dst->groups = NULL;
1165         }
1166
1167         if (src->ptok) {
1168                 dst->ptok = dup_nt_token(dst, src->ptok);
1169                 if (!dst->ptok) {
1170                         TALLOC_FREE(dst);
1171                         return NULL;
1172                 }
1173         }
1174         
1175         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1176                                                 src->user_session_key.length);
1177
1178         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1179                                                 src->lm_session_key.length);
1180
1181         dst->sam_account = samu_new(NULL);
1182         if (!dst->sam_account) {
1183                 TALLOC_FREE(dst);
1184                 return NULL;
1185         }
1186
1187         if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1188                 TALLOC_FREE(dst);
1189                 return NULL;
1190         }
1191         
1192         dst->pam_handle = NULL;
1193         dst->unix_name = talloc_strdup(dst, src->unix_name);
1194         if (!dst->unix_name) {
1195                 TALLOC_FREE(dst);
1196                 return NULL;
1197         }
1198
1199         return dst;
1200 }
1201
1202 static auth_serversupplied_info *guest_info = NULL;
1203
1204 bool init_guest_info(void)
1205 {
1206         if (guest_info != NULL)
1207                 return True;
1208
1209         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1210 }
1211
1212 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1213 {
1214         *server_info = copy_serverinfo(guest_info);
1215         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1216 }
1217
1218 bool copy_current_user(struct current_user *dst, struct current_user *src)
1219 {
1220         gid_t *groups;
1221         NT_USER_TOKEN *nt_token;
1222
1223         groups = (gid_t *)memdup(src->ut.groups,
1224                                  sizeof(gid_t) * src->ut.ngroups);
1225         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1226                 return False;
1227         }
1228
1229         nt_token = dup_nt_token(NULL, src->nt_user_token);
1230         if (nt_token == NULL) {
1231                 SAFE_FREE(groups);
1232                 return False;
1233         }
1234
1235         dst->conn = src->conn;
1236         dst->vuid = src->vuid;
1237         dst->ut.uid = src->ut.uid;
1238         dst->ut.gid = src->ut.gid;
1239         dst->ut.ngroups = src->ut.ngroups;
1240         dst->ut.groups = groups;
1241         dst->nt_user_token = nt_token;
1242         return True;
1243 }
1244
1245 bool set_current_user_guest(struct current_user *dst)
1246 {
1247         gid_t *groups;
1248         NT_USER_TOKEN *nt_token;
1249
1250         groups = (gid_t *)memdup(guest_info->groups,
1251                                  sizeof(gid_t) * guest_info->n_groups);
1252         if (groups == NULL) {
1253                 return False;
1254         }
1255
1256         nt_token = dup_nt_token(NULL, guest_info->ptok);
1257         if (nt_token == NULL) {
1258                 SAFE_FREE(groups);
1259                 return False;
1260         }
1261
1262         TALLOC_FREE(dst->nt_user_token);
1263         SAFE_FREE(dst->ut.groups);
1264
1265         /* dst->conn is never really dereferenced, it's only tested for
1266          * equality in uid.c */
1267         dst->conn = NULL;
1268
1269         dst->vuid = UID_FIELD_INVALID;
1270         dst->ut.uid = guest_info->uid;
1271         dst->ut.gid = guest_info->gid;
1272         dst->ut.ngroups = guest_info->n_groups;
1273         dst->ut.groups = groups;
1274         dst->nt_user_token = nt_token;
1275         return True;
1276 }
1277
1278 /***************************************************************************
1279  Purely internal function for make_server_info_info3
1280  Fill the sam account from getpwnam
1281 ***************************************************************************/
1282 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1283                                  const char *domain,
1284                                  const char *username,
1285                                  char **found_username,
1286                                  uid_t *uid, gid_t *gid,
1287                                  struct samu *account,
1288                                  bool *username_was_mapped)
1289 {
1290         NTSTATUS nt_status;
1291         fstring dom_user, lower_username;
1292         fstring real_username;
1293         struct passwd *passwd;
1294
1295         fstrcpy( lower_username, username );
1296         strlower_m( lower_username );
1297
1298         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1299                 lower_username);
1300
1301         /* Get the passwd struct.  Try to create the account is necessary. */
1302
1303         *username_was_mapped = map_username( dom_user );
1304
1305         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1306                 return NT_STATUS_NO_SUCH_USER;
1307
1308         *uid = passwd->pw_uid;
1309         *gid = passwd->pw_gid;
1310
1311         /* This is pointless -- there is no suport for differing 
1312            unix and windows names.  Make sure to always store the 
1313            one we actually looked up and succeeded. Have I mentioned
1314            why I hate the 'winbind use default domain' parameter?   
1315                                          --jerry              */
1316            
1317         *found_username = talloc_strdup( mem_ctx, real_username );
1318         
1319         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1320
1321         nt_status = samu_set_unix( account, passwd );
1322         
1323         TALLOC_FREE(passwd);
1324         
1325         return nt_status;
1326 }
1327
1328 /****************************************************************************
1329  Wrapper to allow the getpwnam() call to strip the domain name and 
1330  try again in case a local UNIX user is already there.  Also run through 
1331  the username if we fallback to the username only.
1332  ****************************************************************************/
1333  
1334 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1335                              fstring save_username, bool create )
1336 {
1337         struct passwd *pw = NULL;
1338         char *p;
1339         fstring username;
1340         
1341         /* we only save a copy of the username it has been mangled 
1342            by winbindd use default domain */
1343            
1344         save_username[0] = '\0';
1345            
1346         /* don't call map_username() here since it has to be done higher 
1347            up the stack so we don't call it mutliple times */
1348
1349         fstrcpy( username, domuser );
1350         
1351         p = strchr_m( username, *lp_winbind_separator() );
1352         
1353         /* code for a DOMAIN\user string */
1354         
1355         if ( p ) {
1356                 fstring strip_username;
1357
1358                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1359                 if ( pw ) {     
1360                         /* make sure we get the case of the username correct */
1361                         /* work around 'winbind use default domain = yes' */
1362
1363                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1364                                 char *domain;
1365                                 
1366                                 /* split the domain and username into 2 strings */
1367                                 *p = '\0';
1368                                 domain = username;
1369
1370                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1371                         }
1372                         else
1373                                 fstrcpy( save_username, pw->pw_name );
1374
1375                         /* whew -- done! */             
1376                         return pw;
1377                 }
1378
1379                 /* setup for lookup of just the username */
1380                 /* remember that p and username are overlapping memory */
1381
1382                 p++;
1383                 fstrcpy( strip_username, p );
1384                 fstrcpy( username, strip_username );
1385         }
1386         
1387         /* just lookup a plain username */
1388         
1389         pw = Get_Pwnam_alloc(mem_ctx, username);
1390                 
1391         /* Create local user if requested but only if winbindd
1392            is not running.  We need to protect against cases
1393            where winbindd is failing and then prematurely
1394            creating users in /etc/passwd */
1395         
1396         if ( !pw && create && !winbind_ping() ) {
1397                 /* Don't add a machine account. */
1398                 if (username[strlen(username)-1] == '$')
1399                         return NULL;
1400
1401                 smb_create_user(NULL, username, NULL);
1402                 pw = Get_Pwnam_alloc(mem_ctx, username);
1403         }
1404         
1405         /* one last check for a valid passwd struct */
1406         
1407         if ( pw )
1408                 fstrcpy( save_username, pw->pw_name );
1409
1410         return pw;
1411 }
1412
1413 /***************************************************************************
1414  Make a server_info struct from the info3 returned by a domain logon 
1415 ***************************************************************************/
1416
1417 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1418                                 const char *sent_nt_username,
1419                                 const char *domain,
1420                                 auth_serversupplied_info **server_info, 
1421                                 NET_USER_INFO_3 *info3) 
1422 {
1423         static const char zeros[16] = { 0, };
1424
1425         NTSTATUS nt_status = NT_STATUS_OK;
1426         char *found_username;
1427         const char *nt_domain;
1428         const char *nt_username;
1429         struct samu *sam_account = NULL;
1430         DOM_SID user_sid;
1431         DOM_SID group_sid;
1432         bool username_was_mapped;
1433
1434         uid_t uid;
1435         gid_t gid;
1436
1437         auth_serversupplied_info *result;
1438
1439         /* 
1440            Here is where we should check the list of
1441            trusted domains, and verify that the SID 
1442            matches.
1443         */
1444
1445         sid_copy(&user_sid, &info3->dom_sid.sid);
1446         if (!sid_append_rid(&user_sid, info3->user_rid)) {
1447                 return NT_STATUS_INVALID_PARAMETER;
1448         }
1449         
1450         sid_copy(&group_sid, &info3->dom_sid.sid);
1451         if (!sid_append_rid(&group_sid, info3->group_rid)) {
1452                 return NT_STATUS_INVALID_PARAMETER;
1453         }
1454
1455         if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1456                 /* If the server didn't give us one, just use the one we sent
1457                  * them */
1458                 nt_username = sent_nt_username;
1459         }
1460
1461         if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1462                 /* If the server didn't give us one, just use the one we sent
1463                  * them */
1464                 nt_domain = domain;
1465         }
1466         
1467         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1468            add user script (2.2.x behavior).
1469
1470            We use the _unmapped_ username here in an attempt to provide
1471            consistent username mapping behavior between kerberos and NTLM[SSP]
1472            authentication in domain mode security.  I.E. Username mapping
1473            should be applied to the fully qualified username
1474            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1475            called map_username() unnecessarily in make_user_info_map() but
1476            that is how the current code is designed.  Making the change here
1477            is the least disruptive place.  -- jerry */
1478            
1479         if ( !(sam_account = samu_new( NULL )) ) {
1480                 return NT_STATUS_NO_MEMORY;
1481         }
1482
1483         /* this call will try to create the user if necessary */
1484
1485         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1486                                      &found_username, &uid, &gid, sam_account,
1487                                      &username_was_mapped);
1488
1489         
1490         /* if we still don't have a valid unix account check for 
1491           'map to guest = bad uid' */
1492           
1493         if (!NT_STATUS_IS_OK(nt_status)) {
1494                 TALLOC_FREE( sam_account );
1495                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1496                         make_server_info_guest(server_info); 
1497                         return NT_STATUS_OK;
1498                 }
1499                 return nt_status;
1500         }
1501                 
1502         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1503                 TALLOC_FREE(sam_account);
1504                 return NT_STATUS_NO_MEMORY;
1505         }
1506
1507         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1508                 TALLOC_FREE(sam_account);
1509                 return NT_STATUS_NO_MEMORY;
1510         }
1511
1512         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1513                 TALLOC_FREE(sam_account);
1514                 return NT_STATUS_NO_MEMORY;
1515         }
1516
1517         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1518                 TALLOC_FREE(sam_account);
1519                 return NT_STATUS_UNSUCCESSFUL;
1520         }
1521
1522         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1523                 TALLOC_FREE(sam_account);
1524                 return NT_STATUS_UNSUCCESSFUL;
1525         }
1526                 
1527         if (!pdb_set_fullname(sam_account,
1528                               unistr2_static(&(info3->uni_full_name)), 
1529                               PDB_CHANGED)) {
1530                 TALLOC_FREE(sam_account);
1531                 return NT_STATUS_NO_MEMORY;
1532         }
1533
1534         if (!pdb_set_logon_script(sam_account,
1535                                   unistr2_static(&(info3->uni_logon_script)),
1536                                   PDB_CHANGED)) {
1537                 TALLOC_FREE(sam_account);
1538                 return NT_STATUS_NO_MEMORY;
1539         }
1540
1541         if (!pdb_set_profile_path(sam_account,
1542                                   unistr2_static(&(info3->uni_profile_path)),
1543                                   PDB_CHANGED)) {
1544                 TALLOC_FREE(sam_account);
1545                 return NT_STATUS_NO_MEMORY;
1546         }
1547
1548         if (!pdb_set_homedir(sam_account,
1549                              unistr2_static(&(info3->uni_home_dir)),
1550                              PDB_CHANGED)) {
1551                 TALLOC_FREE(sam_account);
1552                 return NT_STATUS_NO_MEMORY;
1553         }
1554
1555         if (!pdb_set_dir_drive(sam_account,
1556                                unistr2_static(&(info3->uni_dir_drive)),
1557                                PDB_CHANGED)) {
1558                 TALLOC_FREE(sam_account);
1559                 return NT_STATUS_NO_MEMORY;
1560         }
1561
1562         if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) {
1563                 TALLOC_FREE(sam_account);
1564                 return NT_STATUS_NO_MEMORY;
1565         }
1566
1567         if (!pdb_set_pass_last_set_time(
1568                     sam_account,
1569                     nt_time_to_unix(info3->pass_last_set_time),
1570                     PDB_CHANGED)) {
1571                 TALLOC_FREE(sam_account);
1572                 return NT_STATUS_NO_MEMORY;
1573         }
1574
1575         if (!pdb_set_pass_can_change_time(
1576                     sam_account,
1577                     nt_time_to_unix(info3->pass_can_change_time),
1578                     PDB_CHANGED)) {
1579                 TALLOC_FREE(sam_account);
1580                 return NT_STATUS_NO_MEMORY;
1581         }
1582
1583         if (!pdb_set_pass_must_change_time(
1584                     sam_account,
1585                     nt_time_to_unix(info3->pass_must_change_time),
1586                     PDB_CHANGED)) {
1587                 TALLOC_FREE(sam_account);
1588                 return NT_STATUS_NO_MEMORY;
1589         }
1590
1591         result = make_server_info(NULL);
1592         if (result == NULL) {
1593                 DEBUG(4, ("make_server_info failed!\n"));
1594                 TALLOC_FREE(sam_account);
1595                 return NT_STATUS_NO_MEMORY;
1596         }
1597
1598         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1599            valid struct samu) */
1600                    
1601         result->sam_account = sam_account;
1602         result->unix_name = talloc_strdup(result, found_username);
1603
1604         /* Fill in the unix info we found on the way */
1605
1606         result->uid = uid;
1607         result->gid = gid;
1608
1609         /* Create a 'combined' list of all SIDs we might want in the SD */
1610
1611         result->num_sids = 0;
1612         result->sids = NULL;
1613
1614         nt_status = sid_array_from_info3(result, info3,
1615                                          &result->sids,
1616                                          &result->num_sids,
1617                                          False);
1618         if (!NT_STATUS_IS_OK(nt_status)) {
1619                 TALLOC_FREE(result);
1620                 return nt_status;
1621         }
1622
1623         result->login_server = unistr2_tdup(result, 
1624                                             &(info3->uni_logon_srv));
1625
1626         /* ensure we are never given NULL session keys */
1627         
1628         if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1629                 result->user_session_key = data_blob_null;
1630         } else {
1631                 result->user_session_key = data_blob_talloc(
1632                         result, info3->user_sess_key,
1633                         sizeof(info3->user_sess_key));
1634         }
1635
1636         if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1637                 result->lm_session_key = data_blob_null;
1638         } else {
1639                 result->lm_session_key = data_blob_talloc(
1640                         result, info3->lm_sess_key,
1641                         sizeof(info3->lm_sess_key));
1642         }
1643
1644         result->was_mapped = username_was_mapped;
1645
1646         *server_info = result;
1647
1648         return NT_STATUS_OK;
1649 }
1650
1651 /***************************************************************************
1652  Free a user_info struct
1653 ***************************************************************************/
1654
1655 void free_user_info(auth_usersupplied_info **user_info)
1656 {
1657         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1658         if (*user_info != NULL) {
1659                 if ((*user_info)->smb_name) {
1660                         DEBUG(10,("structure was created for %s\n",
1661                                   (*user_info)->smb_name));
1662                 }
1663                 SAFE_FREE((*user_info)->smb_name);
1664                 SAFE_FREE((*user_info)->internal_username);
1665                 SAFE_FREE((*user_info)->client_domain);
1666                 SAFE_FREE((*user_info)->domain);
1667                 SAFE_FREE((*user_info)->wksta_name);
1668                 data_blob_free(&(*user_info)->lm_resp);
1669                 data_blob_free(&(*user_info)->nt_resp);
1670                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1671                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1672                 data_blob_clear_free(&(*user_info)->plaintext_password);
1673                 ZERO_STRUCT(**user_info);
1674         }
1675         SAFE_FREE(*user_info);
1676 }
1677
1678 /***************************************************************************
1679  Make an auth_methods struct
1680 ***************************************************************************/
1681
1682 bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
1683 {
1684         if (!auth_context) {
1685                 smb_panic("no auth_context supplied to "
1686                           "make_auth_methods()!\n");
1687         }
1688
1689         if (!auth_method) {
1690                 smb_panic("make_auth_methods: pointer to auth_method pointer "
1691                           "is NULL!\n");
1692         }
1693
1694         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1695         if (!*auth_method) {
1696                 DEBUG(0,("make_auth_method: malloc failed!\n"));
1697                 return False;
1698         }
1699         ZERO_STRUCTP(*auth_method);
1700         
1701         return True;
1702 }
1703
1704 /**
1705  * Verify whether or not given domain is trusted.
1706  *
1707  * @param domain_name name of the domain to be verified
1708  * @return true if domain is one of the trusted once or
1709  *         false if otherwise
1710  **/
1711
1712 bool is_trusted_domain(const char* dom_name)
1713 {
1714         DOM_SID trustdom_sid;
1715         bool ret;
1716
1717         /* no trusted domains for a standalone server */
1718
1719         if ( lp_server_role() == ROLE_STANDALONE )
1720                 return False;
1721
1722         /* if we are a DC, then check for a direct trust relationships */
1723
1724         if ( IS_DC ) {
1725                 become_root();
1726                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1727                           "[%s]\n", dom_name ));
1728                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1729                 unbecome_root();
1730                 if (ret)
1731                         return True;
1732         }
1733         else {
1734                 NSS_STATUS result;
1735
1736                 /* If winbind is around, ask it */
1737
1738                 result = wb_is_trusted_domain(dom_name);
1739
1740                 if (result == NSS_STATUS_SUCCESS) {
1741                         return True;
1742                 }
1743
1744                 if (result == NSS_STATUS_NOTFOUND) {
1745                         /* winbind could not find the domain */
1746                         return False;
1747                 }
1748
1749                 /* The only other possible result is that winbind is not up
1750                    and running. We need to update the trustdom_cache
1751                    ourselves */
1752                 
1753                 update_trustdom_cache();
1754         }
1755
1756         /* now the trustdom cache should be available a DC could still
1757          * have a transitive trust so fall back to the cache of trusted
1758          * domains (like a domain member would use  */
1759
1760         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1761                 return True;
1762         }
1763
1764         return False;
1765 }
1766