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