Fix valgrind error when running under share level security. plaintext_password
[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 #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 int server_info_dtor(struct auth_serversupplied_info *server_info)
497 {
498         TALLOC_FREE(server_info->sam_account);
499         ZERO_STRUCTP(server_info);
500         return 0;
501 }
502
503 /***************************************************************************
504  Make a server_info struct. Free with TALLOC_FREE().
505 ***************************************************************************/
506
507 static struct auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
508 {
509         struct auth_serversupplied_info *result;
510
511         result = TALLOC_ZERO_P(mem_ctx, struct auth_serversupplied_info);
512         if (result == NULL) {
513                 DEBUG(0, ("talloc failed\n"));
514                 return NULL;
515         }
516
517         talloc_set_destructor(result, server_info_dtor);
518
519         /* Initialise the uid and gid values to something non-zero
520            which may save us from giving away root access if there
521            is a bug in allocating these fields. */
522
523         result->utok.uid = -1;
524         result->utok.gid = -1;
525         return result;
526 }
527
528 static char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
529 {
530         fstring tmp;
531
532         alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
533         return talloc_strdup(mem_ctx, tmp);
534 }
535
536 /***************************************************************************
537  Is the incoming username our own machine account ?
538  If so, the connection is almost certainly from winbindd.
539 ***************************************************************************/
540
541 static bool is_our_machine_account(const char *username)
542 {
543         bool ret;
544         char *truncname = NULL;
545         size_t ulen = strlen(username);
546
547         if (ulen == 0 || username[ulen-1] != '$') {
548                 return false;
549         }
550         truncname = SMB_STRDUP(username);
551         if (!truncname) {
552                 return false;
553         }
554         truncname[ulen-1] = '\0';
555         ret = strequal(truncname, global_myname());
556         SAFE_FREE(truncname);
557         return ret;
558 }
559
560 /***************************************************************************
561  Make (and fill) a user_info struct from a struct samu
562 ***************************************************************************/
563
564 NTSTATUS make_server_info_sam(struct auth_serversupplied_info **server_info,
565                               struct samu *sampass)
566 {
567         struct passwd *pwd;
568         gid_t *gids;
569         struct auth_serversupplied_info *result;
570         const char *username = pdb_get_username(sampass);
571         NTSTATUS status;
572
573         if ( !(result = make_server_info(NULL)) ) {
574                 return NT_STATUS_NO_MEMORY;
575         }
576
577         if ( !(pwd = getpwnam_alloc(result, username)) ) {
578                 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
579                           pdb_get_username(sampass)));
580                 TALLOC_FREE(result);
581                 return NT_STATUS_NO_SUCH_USER;
582         }
583
584         result->sam_account = sampass;
585         result->unix_name = pwd->pw_name;
586         /* Ensure that we keep pwd->pw_name, because we will free pwd below */
587         talloc_steal(result, pwd->pw_name);
588         result->utok.gid = pwd->pw_gid;
589         result->utok.uid = pwd->pw_uid;
590
591         TALLOC_FREE(pwd);
592
593         result->sanitized_username = sanitize_username(result,
594                                                        result->unix_name);
595         if (result->sanitized_username == NULL) {
596                 TALLOC_FREE(result);
597                 return NT_STATUS_NO_MEMORY;
598         }
599
600         if (IS_DC && is_our_machine_account(username)) {
601                 /*
602                  * Ensure for a connection from our own
603                  * machine account (from winbindd on a DC)
604                  * there are no supplementary groups.
605                  * Prevents loops in calling gid_to_sid().
606                  */
607                 result->sids = NULL;
608                 gids = NULL;
609                 result->num_sids = 0;
610
611                 /*
612                  * This is a hack of monstrous proportions.
613                  * If we know it's winbindd talking to us,
614                  * we know we must never recurse into it,
615                  * so turn off contacting winbindd for this
616                  * entire process. This will get fixed when
617                  * winbindd doesn't need to talk to smbd on
618                  * a PDC. JRA.
619                  */
620
621                 (void)winbind_off();
622
623                 DEBUG(10, ("make_server_info_sam: our machine account %s "
624                         "setting supplementary group list empty and "
625                         "turning off winbindd requests.\n",
626                         username));
627         } else {
628                 status = pdb_enum_group_memberships(result, sampass,
629                                             &result->sids, &gids,
630                                             &result->num_sids);
631
632                 if (!NT_STATUS_IS_OK(status)) {
633                         DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
634                                    nt_errstr(status)));
635                         result->sam_account = NULL; /* Don't free on error exit. */
636                         TALLOC_FREE(result);
637                         return status;
638                 }
639         }
640
641         /* For now we throw away the gids and convert via sid_to_gid
642          * later. This needs fixing, but I'd like to get the code straight and
643          * simple first. */
644
645         TALLOC_FREE(gids);
646
647         DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
648                  pdb_get_username(sampass), result->unix_name));
649
650         *server_info = result;
651         /* Ensure that the sampass will be freed with the result */
652         talloc_steal(result, sampass);
653
654         return NT_STATUS_OK;
655 }
656
657 static NTSTATUS log_nt_token(NT_USER_TOKEN *token)
658 {
659         TALLOC_CTX *frame = talloc_stackframe();
660         char *command;
661         char *group_sidstr;
662         size_t i;
663
664         if ((lp_log_nt_token_command() == NULL) ||
665             (strlen(lp_log_nt_token_command()) == 0)) {
666                 TALLOC_FREE(frame);
667                 return NT_STATUS_OK;
668         }
669
670         group_sidstr = talloc_strdup(frame, "");
671         for (i=1; i<token->num_sids; i++) {
672                 group_sidstr = talloc_asprintf(
673                         frame, "%s %s", group_sidstr,
674                         sid_string_talloc(frame, &token->user_sids[i]));
675         }
676
677         command = talloc_string_sub(
678                 frame, lp_log_nt_token_command(),
679                 "%s", sid_string_talloc(frame, &token->user_sids[0]));
680         command = talloc_string_sub(frame, command, "%t", group_sidstr);
681
682         if (command == NULL) {
683                 TALLOC_FREE(frame);
684                 return NT_STATUS_NO_MEMORY;
685         }
686
687         DEBUG(8, ("running command: [%s]\n", command));
688         if (smbrun(command, NULL) != 0) {
689                 DEBUG(0, ("Could not log NT token\n"));
690                 TALLOC_FREE(frame);
691                 return NT_STATUS_ACCESS_DENIED;
692         }
693
694         TALLOC_FREE(frame);
695         return NT_STATUS_OK;
696 }
697
698 /*
699  * Create the token to use from server_info->sam_account and
700  * server_info->sids (the info3/sam groups). Find the unix gids.
701  */
702
703 NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
704 {
705         NTSTATUS status;
706         size_t i;
707         struct dom_sid tmp_sid;
708
709         /*
710          * If winbind is not around, we can not make much use of the SIDs the
711          * domain controller provided us with. Likewise if the user name was
712          * mapped to some local unix user.
713          */
714
715         if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
716             (server_info->nss_token)) {
717                 status = create_token_from_username(server_info,
718                                                     server_info->unix_name,
719                                                     server_info->guest,
720                                                     &server_info->utok.uid,
721                                                     &server_info->utok.gid,
722                                                     &server_info->unix_name,
723                                                     &server_info->ptok);
724
725         } else {
726                 server_info->ptok = create_local_nt_token(
727                         server_info,
728                         pdb_get_user_sid(server_info->sam_account),
729                         server_info->guest,
730                         server_info->num_sids, server_info->sids);
731                 status = server_info->ptok ?
732                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
733         }
734
735         if (!NT_STATUS_IS_OK(status)) {
736                 return status;
737         }
738
739         /* Convert the SIDs to gids. */
740
741         server_info->utok.ngroups = 0;
742         server_info->utok.groups = NULL;
743
744         /* Start at index 1, where the groups start. */
745
746         for (i=1; i<server_info->ptok->num_sids; i++) {
747                 gid_t gid;
748                 DOM_SID *sid = &server_info->ptok->user_sids[i];
749
750                 if (!sid_to_gid(sid, &gid)) {
751                         DEBUG(10, ("Could not convert SID %s to gid, "
752                                    "ignoring it\n", sid_string_dbg(sid)));
753                         continue;
754                 }
755                 add_gid_to_array_unique(server_info, gid,
756                                         &server_info->utok.groups,
757                                         &server_info->utok.ngroups);
758         }
759
760         /*
761          * Add the "Unix Group" SID for each gid to catch mapped groups
762          * and their Unix equivalent.  This is to solve the backwards
763          * compatibility problem of 'valid users = +ntadmin' where
764          * ntadmin has been paired with "Domain Admins" in the group
765          * mapping table.  Otherwise smb.conf would need to be changed
766          * to 'valid user = "Domain Admins"'.  --jerry
767          *
768          * For consistency we also add the "Unix User" SID,
769          * so that the complete unix token is represented within
770          * the nt token.
771          */
772
773         if (!uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid)) {
774                 DEBUG(1,("create_local_token: Failed to create SID "
775                         "for uid %u!\n", (unsigned int)server_info->utok.uid));
776         }
777         add_sid_to_array_unique(server_info->ptok, &tmp_sid,
778                                 &server_info->ptok->user_sids,
779                                 &server_info->ptok->num_sids);
780
781         for ( i=0; i<server_info->utok.ngroups; i++ ) {
782                 if (!gid_to_unix_groups_sid( server_info->utok.groups[i], &tmp_sid ) ) {
783                         DEBUG(1,("create_local_token: Failed to create SID "
784                                 "for gid %u!\n", (unsigned int)server_info->utok.groups[i]));
785                         continue;
786                 }
787                 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
788                                         &server_info->ptok->user_sids,
789                                         &server_info->ptok->num_sids);
790         }
791
792         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
793         debug_unix_user_token(DBGC_AUTH, 10,
794                               server_info->utok.uid,
795                               server_info->utok.gid,
796                               server_info->utok.ngroups,
797                               server_info->utok.groups);
798
799         status = log_nt_token(server_info->ptok);
800         return status;
801 }
802
803 /*
804  * Create an artificial NT token given just a username. (Initially intended
805  * for force user)
806  *
807  * We go through lookup_name() to avoid problems we had with 'winbind use
808  * default domain'.
809  *
810  * We have 3 cases:
811  *
812  * unmapped unix users: Go directly to nss to find the user's group.
813  *
814  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
815  *
816  * If the user is provided by winbind, the primary gid is set to "domain
817  * users" of the user's domain. For an explanation why this is necessary, see
818  * the thread starting at
819  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
820  */
821
822 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
823                                     bool is_guest,
824                                     uid_t *uid, gid_t *gid,
825                                     char **found_username,
826                                     struct nt_user_token **token)
827 {
828         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
829         TALLOC_CTX *tmp_ctx;
830         DOM_SID user_sid;
831         enum lsa_SidType type;
832         gid_t *gids;
833         DOM_SID *group_sids;
834         DOM_SID unix_group_sid;
835         size_t num_group_sids;
836         size_t num_gids;
837         size_t i;
838
839         tmp_ctx = talloc_new(NULL);
840         if (tmp_ctx == NULL) {
841                 DEBUG(0, ("talloc_new failed\n"));
842                 return NT_STATUS_NO_MEMORY;
843         }
844
845         if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
846                          NULL, NULL, &user_sid, &type)) {
847                 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
848                 goto done;
849         }
850
851         if (type != SID_NAME_USER) {
852                 DEBUG(1, ("%s is a %s, not a user\n", username,
853                           sid_type_lookup(type)));
854                 goto done;
855         }
856
857         if (sid_check_is_in_our_domain(&user_sid)) {
858                 bool ret;
859
860                 /* This is a passdb user, so ask passdb */
861
862                 struct samu *sam_acct = NULL;
863
864                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
865                         result = NT_STATUS_NO_MEMORY;
866                         goto done;
867                 }
868
869                 become_root();
870                 ret = pdb_getsampwsid(sam_acct, &user_sid);
871                 unbecome_root();
872
873                 if (!ret) {
874                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
875                                   sid_string_dbg(&user_sid), username));
876                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
877                         goto unix_user;
878                 }
879
880                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
881                                                     &group_sids, &gids,
882                                                     &num_group_sids);
883                 if (!NT_STATUS_IS_OK(result)) {
884                         DEBUG(1, ("enum_group_memberships failed for %s (%s): "
885                                   "%s\n", username, sid_string_dbg(&user_sid),
886                                   nt_errstr(result)));
887                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
888                         goto unix_user;
889                 }
890
891                 /* see the smb_panic() in pdb_default_enum_group_memberships */
892                 SMB_ASSERT(num_group_sids > 0); 
893
894                 *gid = gids[0];
895
896                 /* Ensure we're returning the found_username on the right context. */
897                 *found_username = talloc_strdup(mem_ctx,
898                                                 pdb_get_username(sam_acct));
899
900                 /*
901                  * If the SID from lookup_name() was the guest sid, passdb knows
902                  * about the mapping of guest sid to lp_guestaccount()
903                  * username and will return the unix_pw info for a guest
904                  * user. Use it if it's there, else lookup the *uid details
905                  * using getpwnam_alloc(). See bug #6291 for details. JRA.
906                  */
907
908                 /* We must always assign the *uid. */
909                 if (sam_acct->unix_pw == NULL) {
910                         struct passwd *pwd = getpwnam_alloc(sam_acct, *found_username );
911                         if (!pwd) {
912                                 DEBUG(10, ("getpwnam_alloc failed for %s\n",
913                                         *found_username));
914                                 result = NT_STATUS_NO_SUCH_USER;
915                                 goto done;
916                         }
917                         result = samu_set_unix(sam_acct, pwd );
918                         if (!NT_STATUS_IS_OK(result)) {
919                                 DEBUG(10, ("samu_set_unix failed for %s\n",
920                                         *found_username));
921                                 result = NT_STATUS_NO_SUCH_USER;
922                                 goto done;
923                         }
924                 }
925                 *uid = sam_acct->unix_pw->pw_uid;
926
927         } else  if (sid_check_is_in_unix_users(&user_sid)) {
928
929                 /* This is a unix user not in passdb. We need to ask nss
930                  * directly, without consulting passdb */
931
932                 struct passwd *pass;
933
934                 /*
935                  * This goto target is used as a fallback for the passdb
936                  * case. The concrete bug report is when passdb gave us an
937                  * unmapped gid.
938                  */
939
940         unix_user:
941
942                 if (!sid_to_uid(&user_sid, uid)) {
943                         DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n",
944                                   username, sid_string_dbg(&user_sid)));
945                         result = NT_STATUS_NO_SUCH_USER;
946                         goto done;
947                 }
948
949                 uid_to_unix_users_sid(*uid, &user_sid);
950
951                 pass = getpwuid_alloc(tmp_ctx, *uid);
952                 if (pass == NULL) {
953                         DEBUG(1, ("getpwuid(%u) for user %s failed\n",
954                                   (unsigned int)*uid, username));
955                         goto done;
956                 }
957
958                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
959                                          &gids, &num_group_sids)) {
960                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
961                                   username));
962                         goto done;
963                 }
964
965                 if (num_group_sids) {
966                         group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
967                         if (group_sids == NULL) {
968                                 DEBUG(1, ("TALLOC_ARRAY failed\n"));
969                                 result = NT_STATUS_NO_MEMORY;
970                                 goto done;
971                         }
972                 } else {
973                         group_sids = NULL;
974                 }
975
976                 for (i=0; i<num_group_sids; i++) {
977                         gid_to_sid(&group_sids[i], gids[i]);
978                 }
979
980                 /* In getgroups_unix_user we always set the primary gid */
981                 SMB_ASSERT(num_group_sids > 0); 
982
983                 *gid = gids[0];
984
985                 /* Ensure we're returning the found_username on the right context. */
986                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
987         } else {
988
989                 /* This user is from winbind, force the primary gid to the
990                  * user's "domain users" group. Under certain circumstances
991                  * (user comes from NT4), this might be a loss of
992                  * information. But we can not rely on winbind getting the
993                  * correct info. AD might prohibit winbind looking up that
994                  * information. */
995
996                 uint32 dummy;
997
998                 /* We must always assign the *uid. */
999                 if (!sid_to_uid(&user_sid, uid)) {
1000                         DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n",
1001                                   username, sid_string_dbg(&user_sid)));
1002                         result = NT_STATUS_NO_SUCH_USER;
1003                         goto done;
1004                 }
1005
1006                 num_group_sids = 1;
1007                 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
1008                 if (group_sids == NULL) {
1009                         DEBUG(1, ("TALLOC_ARRAY failed\n"));
1010                         result = NT_STATUS_NO_MEMORY;
1011                         goto done;
1012                 }
1013
1014                 sid_copy(&group_sids[0], &user_sid);
1015                 sid_split_rid(&group_sids[0], &dummy);
1016                 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
1017
1018                 if (!sid_to_gid(&group_sids[0], gid)) {
1019                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1020                                   sid_string_dbg(&group_sids[0])));
1021                         goto done;
1022                 }
1023
1024                 gids = gid;
1025
1026                 /* Ensure we're returning the found_username on the right context. */
1027                 *found_username = talloc_strdup(mem_ctx, username);
1028         }
1029
1030         /* Add the "Unix Group" SID for each gid to catch mapped groups
1031            and their Unix equivalent.  This is to solve the backwards
1032            compatibility problem of 'valid users = +ntadmin' where
1033            ntadmin has been paired with "Domain Admins" in the group
1034            mapping table.  Otherwise smb.conf would need to be changed
1035            to 'valid user = "Domain Admins"'.  --jerry */
1036
1037         num_gids = num_group_sids;
1038         for ( i=0; i<num_gids; i++ ) {
1039                 gid_t high, low;
1040
1041                 /* don't pickup anything managed by Winbind */
1042
1043                 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
1044                         continue;
1045
1046                 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
1047                         DEBUG(1,("create_token_from_username: Failed to create SID "
1048                                 "for gid %u!\n", (unsigned int)gids[i]));
1049                         continue;
1050                 }
1051                 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
1052                                                  &group_sids, &num_group_sids);
1053                 if (!NT_STATUS_IS_OK(result)) {
1054                         goto done;
1055                 }
1056         }
1057
1058         /* Ensure we're creating the nt_token on the right context. */
1059         *token = create_local_nt_token(mem_ctx, &user_sid,
1060                                        is_guest, num_group_sids, group_sids);
1061
1062         if ((*token == NULL) || (*found_username == NULL)) {
1063                 result = NT_STATUS_NO_MEMORY;
1064                 goto done;
1065         }
1066
1067         result = NT_STATUS_OK;
1068  done:
1069         TALLOC_FREE(tmp_ctx);
1070         return result;
1071 }
1072
1073 /***************************************************************************
1074  Build upon create_token_from_username:
1075
1076  Expensive helper function to figure out whether a user given its name is
1077  member of a particular group.
1078 ***************************************************************************/
1079
1080 bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
1081 {
1082         NTSTATUS status;
1083         uid_t uid;
1084         gid_t gid;
1085         char *found_username;
1086         struct nt_user_token *token;
1087         bool result;
1088
1089         TALLOC_CTX *mem_ctx;
1090
1091         mem_ctx = talloc_new(NULL);
1092         if (mem_ctx == NULL) {
1093                 DEBUG(0, ("talloc_new failed\n"));
1094                 return False;
1095         }
1096
1097         status = create_token_from_username(mem_ctx, username, False,
1098                                             &uid, &gid, &found_username,
1099                                             &token);
1100
1101         if (!NT_STATUS_IS_OK(status)) {
1102                 DEBUG(10, ("could not create token for %s\n", username));
1103                 return False;
1104         }
1105
1106         result = nt_token_check_sid(group_sid, token);
1107
1108         TALLOC_FREE(mem_ctx);
1109         return result;
1110 }
1111
1112 bool user_in_group(const char *username, const char *groupname)
1113 {
1114         TALLOC_CTX *mem_ctx;
1115         DOM_SID group_sid;
1116         bool ret;
1117
1118         mem_ctx = talloc_new(NULL);
1119         if (mem_ctx == NULL) {
1120                 DEBUG(0, ("talloc_new failed\n"));
1121                 return False;
1122         }
1123
1124         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1125                           NULL, NULL, &group_sid, NULL);
1126         TALLOC_FREE(mem_ctx);
1127
1128         if (!ret) {
1129                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1130                 return False;
1131         }
1132
1133         return user_in_group_sid(username, &group_sid);
1134 }
1135
1136 /***************************************************************************
1137  Make (and fill) a server_info struct from a 'struct passwd' by conversion
1138  to a struct samu
1139 ***************************************************************************/
1140
1141 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
1142                              char *unix_username,
1143                              struct passwd *pwd)
1144 {
1145         NTSTATUS status;
1146         struct samu *sampass = NULL;
1147         gid_t *gids;
1148         char *qualified_name = NULL;
1149         TALLOC_CTX *mem_ctx = NULL;
1150         DOM_SID u_sid;
1151         enum lsa_SidType type;
1152         struct auth_serversupplied_info *result;
1153
1154         if ( !(sampass = samu_new( NULL )) ) {
1155                 return NT_STATUS_NO_MEMORY;
1156         }
1157
1158         status = samu_set_unix( sampass, pwd );
1159         if (!NT_STATUS_IS_OK(status)) {
1160                 return status;
1161         }
1162
1163         result = make_server_info(NULL);
1164         if (result == NULL) {
1165                 TALLOC_FREE(sampass);
1166                 return NT_STATUS_NO_MEMORY;
1167         }
1168
1169         result->sam_account = sampass;
1170
1171         result->unix_name = talloc_strdup(result, unix_username);
1172         result->sanitized_username = sanitize_username(result, unix_username);
1173
1174         if ((result->unix_name == NULL)
1175             || (result->sanitized_username == NULL)) {
1176                 TALLOC_FREE(sampass);
1177                 TALLOC_FREE(result);
1178                 return NT_STATUS_NO_MEMORY;
1179         }
1180
1181         result->utok.uid = pwd->pw_uid;
1182         result->utok.gid = pwd->pw_gid;
1183
1184         status = pdb_enum_group_memberships(result, sampass,
1185                                             &result->sids, &gids,
1186                                             &result->num_sids);
1187
1188         if (!NT_STATUS_IS_OK(status)) {
1189                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1190                            nt_errstr(status)));
1191                 TALLOC_FREE(result);
1192                 return status;
1193         }
1194
1195         /*
1196          * The SID returned in server_info->sam_account is based
1197          * on our SAM sid even though for a pure UNIX account this should
1198          * not be the case as it doesn't really exist in the SAM db.
1199          * This causes lookups on "[in]valid users" to fail as they
1200          * will lookup this name as a "Unix User" SID to check against
1201          * the user token. Fix this by adding the "Unix User"\unix_username
1202          * SID to the sid array. The correct fix should probably be
1203          * changing the server_info->sam_account user SID to be a
1204          * S-1-22 Unix SID, but this might break old configs where
1205          * plaintext passwords were used with no SAM backend.
1206          */
1207
1208         mem_ctx = talloc_init("make_server_info_pw_tmp");
1209         if (!mem_ctx) {
1210                 TALLOC_FREE(result);
1211                 return NT_STATUS_NO_MEMORY;
1212         }
1213
1214         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
1215                                         unix_users_domain_name(),
1216                                         unix_username );
1217         if (!qualified_name) {
1218                 TALLOC_FREE(result);
1219                 TALLOC_FREE(mem_ctx);
1220                 return NT_STATUS_NO_MEMORY;
1221         }
1222
1223         if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
1224                                                 NULL, NULL,
1225                                                 &u_sid, &type)) {
1226                 TALLOC_FREE(result);
1227                 TALLOC_FREE(mem_ctx);
1228                 return NT_STATUS_NO_SUCH_USER;
1229         }
1230
1231         TALLOC_FREE(mem_ctx);
1232
1233         if (type != SID_NAME_USER) {
1234                 TALLOC_FREE(result);
1235                 return NT_STATUS_NO_SUCH_USER;
1236         }
1237
1238         status = add_sid_to_array_unique(result, &u_sid,
1239                                          &result->sids,
1240                                          &result->num_sids);
1241         if (!NT_STATUS_IS_OK(status)) {
1242                 TALLOC_FREE(result);
1243                 return status;
1244         }
1245
1246         /* For now we throw away the gids and convert via sid_to_gid
1247          * later. This needs fixing, but I'd like to get the code straight and
1248          * simple first. */
1249         TALLOC_FREE(gids);
1250
1251         *server_info = result;
1252
1253         return NT_STATUS_OK;
1254 }
1255
1256 /***************************************************************************
1257  Make (and fill) a user_info struct for a guest login.
1258  This *must* succeed for smbd to start. If there is no mapping entry for
1259  the guest gid, then create one.
1260 ***************************************************************************/
1261
1262 static NTSTATUS make_new_server_info_guest(struct auth_serversupplied_info **server_info)
1263 {
1264         NTSTATUS status;
1265         struct samu *sampass = NULL;
1266         DOM_SID guest_sid;
1267         bool ret;
1268         static const char zeros[16] = {0, };
1269         fstring tmp;
1270
1271         if ( !(sampass = samu_new( NULL )) ) {
1272                 return NT_STATUS_NO_MEMORY;
1273         }
1274
1275         sid_compose(&guest_sid, get_global_sam_sid(), DOMAIN_USER_RID_GUEST);
1276
1277         become_root();
1278         ret = pdb_getsampwsid(sampass, &guest_sid);
1279         unbecome_root();
1280
1281         if (!ret) {
1282                 TALLOC_FREE(sampass);
1283                 return NT_STATUS_NO_SUCH_USER;
1284         }
1285
1286         status = make_server_info_sam(server_info, sampass);
1287         if (!NT_STATUS_IS_OK(status)) {
1288                 TALLOC_FREE(sampass);
1289                 return status;
1290         }
1291
1292         (*server_info)->guest = True;
1293
1294         status = create_local_token(*server_info);
1295         if (!NT_STATUS_IS_OK(status)) {
1296                 DEBUG(10, ("create_local_token failed: %s\n",
1297                            nt_errstr(status)));
1298                 return status;
1299         }
1300
1301         /* annoying, but the Guest really does have a session key, and it is
1302            all zeros! */
1303         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1304         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1305
1306         alpha_strcpy(tmp, pdb_get_username(sampass), ". _-$", sizeof(tmp));
1307         (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp);
1308
1309         return NT_STATUS_OK;
1310 }
1311
1312 /****************************************************************************
1313   Fake a auth_serversupplied_info just from a username
1314 ****************************************************************************/
1315
1316 NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
1317                                        const char *username,
1318                                        bool is_guest,
1319                                        struct auth_serversupplied_info **presult)
1320 {
1321         struct auth_serversupplied_info *result;
1322         struct passwd *pwd;
1323         NTSTATUS status;
1324
1325         pwd = getpwnam_alloc(talloc_tos(), username);
1326         if (pwd == NULL) {
1327                 return NT_STATUS_NO_SUCH_USER;
1328         }
1329
1330         status = make_server_info_pw(&result, pwd->pw_name, pwd);
1331
1332         TALLOC_FREE(pwd);
1333
1334         if (!NT_STATUS_IS_OK(status)) {
1335                 return status;
1336         }
1337
1338         result->nss_token = true;
1339         result->guest = is_guest;
1340
1341         status = create_local_token(result);
1342
1343         if (!NT_STATUS_IS_OK(status)) {
1344                 TALLOC_FREE(result);
1345                 return status;
1346         }
1347
1348         *presult = result;
1349         return NT_STATUS_OK;
1350 }
1351
1352
1353 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
1354                                                  const struct auth_serversupplied_info *src)
1355 {
1356         struct auth_serversupplied_info *dst;
1357
1358         dst = make_server_info(mem_ctx);
1359         if (dst == NULL) {
1360                 return NULL;
1361         }
1362
1363         dst->guest = src->guest;
1364         dst->utok.uid = src->utok.uid;
1365         dst->utok.gid = src->utok.gid;
1366         dst->utok.ngroups = src->utok.ngroups;
1367         if (src->utok.ngroups != 0) {
1368                 dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
1369                         dst, src->utok.groups,
1370                         sizeof(gid_t)*dst->utok.ngroups);
1371         } else {
1372                 dst->utok.groups = NULL;
1373         }
1374
1375         if (src->ptok) {
1376                 dst->ptok = dup_nt_token(dst, src->ptok);
1377                 if (!dst->ptok) {
1378                         TALLOC_FREE(dst);
1379                         return NULL;
1380                 }
1381         }
1382
1383         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1384                                                 src->user_session_key.length);
1385
1386         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1387                                                 src->lm_session_key.length);
1388
1389         dst->sam_account = samu_new(NULL);
1390         if (!dst->sam_account) {
1391                 TALLOC_FREE(dst);
1392                 return NULL;
1393         }
1394
1395         if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1396                 TALLOC_FREE(dst);
1397                 return NULL;
1398         }
1399
1400         dst->pam_handle = NULL;
1401         dst->unix_name = talloc_strdup(dst, src->unix_name);
1402         if (!dst->unix_name) {
1403                 TALLOC_FREE(dst);
1404                 return NULL;
1405         }
1406
1407         dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
1408         if (!dst->sanitized_username) {
1409                 TALLOC_FREE(dst);
1410                 return NULL;
1411         }
1412
1413         return dst;
1414 }
1415
1416 /*
1417  * Set a new session key. Used in the rpc server where we have to override the
1418  * SMB level session key with SystemLibraryDTC
1419  */
1420
1421 bool server_info_set_session_key(struct auth_serversupplied_info *info,
1422                                  DATA_BLOB session_key)
1423 {
1424         TALLOC_FREE(info->user_session_key.data);
1425
1426         info->user_session_key = data_blob_talloc(
1427                 info, session_key.data, session_key.length);
1428
1429         return (info->user_session_key.data != NULL);
1430 }
1431
1432 static struct auth_serversupplied_info *guest_info = NULL;
1433
1434 bool init_guest_info(void)
1435 {
1436         if (guest_info != NULL)
1437                 return True;
1438
1439         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1440 }
1441
1442 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1443                                 struct auth_serversupplied_info **server_info)
1444 {
1445         *server_info = copy_serverinfo(mem_ctx, guest_info);
1446         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1447 }
1448
1449 bool copy_current_user(struct current_user *dst, struct current_user *src)
1450 {
1451         gid_t *groups;
1452         NT_USER_TOKEN *nt_token;
1453
1454         groups = (gid_t *)memdup(src->ut.groups,
1455                                  sizeof(gid_t) * src->ut.ngroups);
1456         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1457                 return False;
1458         }
1459
1460         nt_token = dup_nt_token(NULL, src->nt_user_token);
1461         if (nt_token == NULL) {
1462                 SAFE_FREE(groups);
1463                 return False;
1464         }
1465
1466         dst->conn = src->conn;
1467         dst->vuid = src->vuid;
1468         dst->ut.uid = src->ut.uid;
1469         dst->ut.gid = src->ut.gid;
1470         dst->ut.ngroups = src->ut.ngroups;
1471         dst->ut.groups = groups;
1472         dst->nt_user_token = nt_token;
1473         return True;
1474 }
1475
1476 /***************************************************************************
1477  Purely internal function for make_server_info_info3
1478  Fill the sam account from getpwnam
1479 ***************************************************************************/
1480 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1481                                  const char *domain,
1482                                  const char *username,
1483                                  char **found_username,
1484                                  uid_t *uid, gid_t *gid,
1485                                  struct samu *account,
1486                                  bool *username_was_mapped)
1487 {
1488         struct smbd_server_connection *sconn = smbd_server_conn;
1489         NTSTATUS nt_status;
1490         fstring dom_user, lower_username;
1491         fstring real_username;
1492         struct passwd *passwd;
1493
1494         fstrcpy( lower_username, username );
1495         strlower_m( lower_username );
1496
1497         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1498                 lower_username);
1499
1500         /* Get the passwd struct.  Try to create the account is necessary. */
1501
1502         *username_was_mapped = map_username(sconn, dom_user);
1503
1504         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1505                 return NT_STATUS_NO_SUCH_USER;
1506
1507         *uid = passwd->pw_uid;
1508         *gid = passwd->pw_gid;
1509
1510         /* This is pointless -- there is no suport for differing 
1511            unix and windows names.  Make sure to always store the 
1512            one we actually looked up and succeeded. Have I mentioned
1513            why I hate the 'winbind use default domain' parameter?   
1514                                          --jerry              */
1515
1516         *found_username = talloc_strdup( mem_ctx, real_username );
1517
1518         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1519
1520         nt_status = samu_set_unix( account, passwd );
1521
1522         TALLOC_FREE(passwd);
1523
1524         return nt_status;
1525 }
1526
1527 /****************************************************************************
1528  Wrapper to allow the getpwnam() call to strip the domain name and 
1529  try again in case a local UNIX user is already there.  Also run through 
1530  the username if we fallback to the username only.
1531  ****************************************************************************/
1532
1533 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1534                              fstring save_username, bool create )
1535 {
1536         struct passwd *pw = NULL;
1537         char *p;
1538         fstring username;
1539
1540         /* we only save a copy of the username it has been mangled 
1541            by winbindd use default domain */
1542
1543         save_username[0] = '\0';
1544
1545         /* don't call map_username() here since it has to be done higher 
1546            up the stack so we don't call it mutliple times */
1547
1548         fstrcpy( username, domuser );
1549
1550         p = strchr_m( username, *lp_winbind_separator() );
1551
1552         /* code for a DOMAIN\user string */
1553
1554         if ( p ) {
1555                 fstring strip_username;
1556
1557                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1558                 if ( pw ) {     
1559                         /* make sure we get the case of the username correct */
1560                         /* work around 'winbind use default domain = yes' */
1561
1562                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1563                                 char *domain;
1564
1565                                 /* split the domain and username into 2 strings */
1566                                 *p = '\0';
1567                                 domain = username;
1568
1569                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1570                         }
1571                         else
1572                                 fstrcpy( save_username, pw->pw_name );
1573
1574                         /* whew -- done! */             
1575                         return pw;
1576                 }
1577
1578                 /* setup for lookup of just the username */
1579                 /* remember that p and username are overlapping memory */
1580
1581                 p++;
1582                 fstrcpy( strip_username, p );
1583                 fstrcpy( username, strip_username );
1584         }
1585
1586         /* just lookup a plain username */
1587
1588         pw = Get_Pwnam_alloc(mem_ctx, username);
1589
1590         /* Create local user if requested but only if winbindd
1591            is not running.  We need to protect against cases
1592            where winbindd is failing and then prematurely
1593            creating users in /etc/passwd */
1594
1595         if ( !pw && create && !winbind_ping() ) {
1596                 /* Don't add a machine account. */
1597                 if (username[strlen(username)-1] == '$')
1598                         return NULL;
1599
1600                 _smb_create_user(NULL, username, NULL);
1601                 pw = Get_Pwnam_alloc(mem_ctx, username);
1602         }
1603
1604         /* one last check for a valid passwd struct */
1605
1606         if ( pw )
1607                 fstrcpy( save_username, pw->pw_name );
1608
1609         return pw;
1610 }
1611
1612 /***************************************************************************
1613  Make a server_info struct from the info3 returned by a domain logon 
1614 ***************************************************************************/
1615
1616 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1617                                 const char *sent_nt_username,
1618                                 const char *domain,
1619                                 struct auth_serversupplied_info **server_info,
1620                                 struct netr_SamInfo3 *info3)
1621 {
1622         static const char zeros[16] = {0, };
1623
1624         NTSTATUS nt_status = NT_STATUS_OK;
1625         char *found_username = NULL;
1626         const char *nt_domain;
1627         const char *nt_username;
1628         struct samu *sam_account = NULL;
1629         DOM_SID user_sid;
1630         DOM_SID group_sid;
1631         bool username_was_mapped;
1632
1633         uid_t uid = (uid_t)-1;
1634         gid_t gid = (gid_t)-1;
1635
1636         struct auth_serversupplied_info *result;
1637
1638         /* 
1639            Here is where we should check the list of
1640            trusted domains, and verify that the SID 
1641            matches.
1642         */
1643
1644         if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
1645                 return NT_STATUS_INVALID_PARAMETER;
1646         }
1647
1648         if (!sid_compose(&group_sid, info3->base.domain_sid,
1649                          info3->base.primary_gid)) {
1650                 return NT_STATUS_INVALID_PARAMETER;
1651         }
1652
1653         nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1654         if (!nt_username) {
1655                 /* If the server didn't give us one, just use the one we sent
1656                  * them */
1657                 nt_username = sent_nt_username;
1658         }
1659
1660         nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1661         if (!nt_domain) {
1662                 /* If the server didn't give us one, just use the one we sent
1663                  * them */
1664                 nt_domain = domain;
1665         }
1666
1667         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1668            add user script (2.2.x behavior).
1669
1670            We use the _unmapped_ username here in an attempt to provide
1671            consistent username mapping behavior between kerberos and NTLM[SSP]
1672            authentication in domain mode security.  I.E. Username mapping
1673            should be applied to the fully qualified username
1674            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1675            called map_username() unnecessarily in make_user_info_map() but
1676            that is how the current code is designed.  Making the change here
1677            is the least disruptive place.  -- jerry */
1678
1679         if ( !(sam_account = samu_new( NULL )) ) {
1680                 return NT_STATUS_NO_MEMORY;
1681         }
1682
1683         /* this call will try to create the user if necessary */
1684
1685         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1686                                      &found_username, &uid, &gid, sam_account,
1687                                      &username_was_mapped);
1688
1689
1690         /* if we still don't have a valid unix account check for 
1691           'map to guest = bad uid' */
1692
1693         if (!NT_STATUS_IS_OK(nt_status)) {
1694                 TALLOC_FREE( sam_account );
1695                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1696                         make_server_info_guest(NULL, server_info);
1697                         return NT_STATUS_OK;
1698                 }
1699                 return nt_status;
1700         }
1701
1702         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1703                 TALLOC_FREE(sam_account);
1704                 return NT_STATUS_NO_MEMORY;
1705         }
1706
1707         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1708                 TALLOC_FREE(sam_account);
1709                 return NT_STATUS_NO_MEMORY;
1710         }
1711
1712         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1713                 TALLOC_FREE(sam_account);
1714                 return NT_STATUS_NO_MEMORY;
1715         }
1716
1717         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1718                 TALLOC_FREE(sam_account);
1719                 return NT_STATUS_UNSUCCESSFUL;
1720         }
1721
1722         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1723                 TALLOC_FREE(sam_account);
1724                 return NT_STATUS_UNSUCCESSFUL;
1725         }
1726
1727         if (!pdb_set_fullname(sam_account,
1728                               info3->base.full_name.string,
1729                               PDB_CHANGED)) {
1730                 TALLOC_FREE(sam_account);
1731                 return NT_STATUS_NO_MEMORY;
1732         }
1733
1734         if (!pdb_set_logon_script(sam_account,
1735                                   info3->base.logon_script.string,
1736                                   PDB_CHANGED)) {
1737                 TALLOC_FREE(sam_account);
1738                 return NT_STATUS_NO_MEMORY;
1739         }
1740
1741         if (!pdb_set_profile_path(sam_account,
1742                                   info3->base.profile_path.string,
1743                                   PDB_CHANGED)) {
1744                 TALLOC_FREE(sam_account);
1745                 return NT_STATUS_NO_MEMORY;
1746         }
1747
1748         if (!pdb_set_homedir(sam_account,
1749                              info3->base.home_directory.string,
1750                              PDB_CHANGED)) {
1751                 TALLOC_FREE(sam_account);
1752                 return NT_STATUS_NO_MEMORY;
1753         }
1754
1755         if (!pdb_set_dir_drive(sam_account,
1756                                info3->base.home_drive.string,
1757                                PDB_CHANGED)) {
1758                 TALLOC_FREE(sam_account);
1759                 return NT_STATUS_NO_MEMORY;
1760         }
1761
1762         if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {
1763                 TALLOC_FREE(sam_account);
1764                 return NT_STATUS_NO_MEMORY;
1765         }
1766
1767         if (!pdb_set_pass_last_set_time(
1768                     sam_account,
1769                     nt_time_to_unix(info3->base.last_password_change),
1770                     PDB_CHANGED)) {
1771                 TALLOC_FREE(sam_account);
1772                 return NT_STATUS_NO_MEMORY;
1773         }
1774
1775         if (!pdb_set_pass_can_change_time(
1776                     sam_account,
1777                     nt_time_to_unix(info3->base.allow_password_change),
1778                     PDB_CHANGED)) {
1779                 TALLOC_FREE(sam_account);
1780                 return NT_STATUS_NO_MEMORY;
1781         }
1782
1783         if (!pdb_set_pass_must_change_time(
1784                     sam_account,
1785                     nt_time_to_unix(info3->base.force_password_change),
1786                     PDB_CHANGED)) {
1787                 TALLOC_FREE(sam_account);
1788                 return NT_STATUS_NO_MEMORY;
1789         }
1790
1791         result = make_server_info(NULL);
1792         if (result == NULL) {
1793                 DEBUG(4, ("make_server_info failed!\n"));
1794                 TALLOC_FREE(sam_account);
1795                 return NT_STATUS_NO_MEMORY;
1796         }
1797
1798         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1799            valid struct samu) */
1800
1801         result->sam_account = sam_account;
1802         result->unix_name = talloc_strdup(result, found_username);
1803
1804         result->sanitized_username = sanitize_username(result,
1805                                                        result->unix_name);
1806         if (result->sanitized_username == NULL) {
1807                 TALLOC_FREE(result);
1808                 return NT_STATUS_NO_MEMORY;
1809         }
1810
1811         /* Fill in the unix info we found on the way */
1812
1813         result->utok.uid = uid;
1814         result->utok.gid = gid;
1815
1816         /* Create a 'combined' list of all SIDs we might want in the SD */
1817
1818         result->num_sids = 0;
1819         result->sids = NULL;
1820
1821         nt_status = sid_array_from_info3(result, info3,
1822                                          &result->sids,
1823                                          &result->num_sids,
1824                                          false, false);
1825         if (!NT_STATUS_IS_OK(nt_status)) {
1826                 TALLOC_FREE(result);
1827                 return nt_status;
1828         }
1829
1830         /* Ensure the primary group sid is at position 0. */
1831         sort_sid_array_for_smbd(result, &group_sid);
1832
1833         result->login_server = talloc_strdup(result,
1834                                              info3->base.logon_server.string);
1835
1836         /* ensure we are never given NULL session keys */
1837
1838         if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1839                 result->user_session_key = data_blob_null;
1840         } else {
1841                 result->user_session_key = data_blob_talloc(
1842                         result, info3->base.key.key,
1843                         sizeof(info3->base.key.key));
1844         }
1845
1846         if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1847                 result->lm_session_key = data_blob_null;
1848         } else {
1849                 result->lm_session_key = data_blob_talloc(
1850                         result, info3->base.LMSessKey.key,
1851                         sizeof(info3->base.LMSessKey.key));
1852         }
1853
1854         result->nss_token |= username_was_mapped;
1855
1856         *server_info = result;
1857
1858         return NT_STATUS_OK;
1859 }
1860
1861 /*****************************************************************************
1862  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1863 ******************************************************************************/
1864
1865 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1866                                           const char *sent_nt_username,
1867                                           const char *domain,
1868                                           const struct wbcAuthUserInfo *info,
1869                                           struct auth_serversupplied_info **server_info)
1870 {
1871         static const char zeros[16] = {0, };
1872
1873         NTSTATUS nt_status = NT_STATUS_OK;
1874         char *found_username = NULL;
1875         const char *nt_domain;
1876         const char *nt_username;
1877         struct samu *sam_account = NULL;
1878         DOM_SID user_sid;
1879         DOM_SID group_sid;
1880         bool username_was_mapped;
1881         uint32_t i;
1882
1883         uid_t uid = (uid_t)-1;
1884         gid_t gid = (gid_t)-1;
1885
1886         struct auth_serversupplied_info *result;
1887
1888         result = make_server_info(NULL);
1889         if (result == NULL) {
1890                 DEBUG(4, ("make_server_info failed!\n"));
1891                 return NT_STATUS_NO_MEMORY;
1892         }
1893
1894         /*
1895            Here is where we should check the list of
1896            trusted domains, and verify that the SID
1897            matches.
1898         */
1899
1900         memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
1901         memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
1902
1903         if (info->account_name) {
1904                 nt_username = talloc_strdup(result, info->account_name);
1905         } else {
1906                 /* If the server didn't give us one, just use the one we sent
1907                  * them */
1908                 nt_username = talloc_strdup(result, sent_nt_username);
1909         }
1910         if (!nt_username) {
1911                 TALLOC_FREE(result);
1912                 return NT_STATUS_NO_MEMORY;
1913         }
1914
1915         if (info->domain_name) {
1916                 nt_domain = talloc_strdup(result, info->domain_name);
1917         } else {
1918                 /* If the server didn't give us one, just use the one we sent
1919                  * them */
1920                 nt_domain = talloc_strdup(result, domain);
1921         }
1922         if (!nt_domain) {
1923                 TALLOC_FREE(result);
1924                 return NT_STATUS_NO_MEMORY;
1925         }
1926
1927         /* try to fill the SAM account..  If getpwnam() fails, then try the
1928            add user script (2.2.x behavior).
1929
1930            We use the _unmapped_ username here in an attempt to provide
1931            consistent username mapping behavior between kerberos and NTLM[SSP]
1932            authentication in domain mode security.  I.E. Username mapping
1933            should be applied to the fully qualified username
1934            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1935            called map_username() unnecessarily in make_user_info_map() but
1936            that is how the current code is designed.  Making the change here
1937            is the least disruptive place.  -- jerry */
1938
1939         if ( !(sam_account = samu_new( result )) ) {
1940                 TALLOC_FREE(result);
1941                 return NT_STATUS_NO_MEMORY;
1942         }
1943
1944         /* this call will try to create the user if necessary */
1945
1946         nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
1947                                      &found_username, &uid, &gid, sam_account,
1948                                      &username_was_mapped);
1949
1950         /* if we still don't have a valid unix account check for
1951           'map to guest = bad uid' */
1952
1953         if (!NT_STATUS_IS_OK(nt_status)) {
1954                 TALLOC_FREE( result );
1955                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1956                         make_server_info_guest(NULL, server_info);
1957                         return NT_STATUS_OK;
1958                 }
1959                 return nt_status;
1960         }
1961
1962         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1963                 TALLOC_FREE(result);
1964                 return NT_STATUS_NO_MEMORY;
1965         }
1966
1967         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1968                 TALLOC_FREE(result);
1969                 return NT_STATUS_NO_MEMORY;
1970         }
1971
1972         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1973                 TALLOC_FREE(result);
1974                 return NT_STATUS_NO_MEMORY;
1975         }
1976
1977         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1978                 TALLOC_FREE(result);
1979                 return NT_STATUS_UNSUCCESSFUL;
1980         }
1981
1982         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1983                 TALLOC_FREE(result);
1984                 return NT_STATUS_UNSUCCESSFUL;
1985         }
1986
1987         if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
1988                 TALLOC_FREE(result);
1989                 return NT_STATUS_NO_MEMORY;
1990         }
1991
1992         if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
1993                 TALLOC_FREE(result);
1994                 return NT_STATUS_NO_MEMORY;
1995         }
1996
1997         if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
1998                 TALLOC_FREE(result);
1999                 return NT_STATUS_NO_MEMORY;
2000         }
2001
2002         if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
2003                 TALLOC_FREE(result);
2004                 return NT_STATUS_NO_MEMORY;
2005         }
2006
2007         if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
2008                 TALLOC_FREE(result);
2009                 return NT_STATUS_NO_MEMORY;
2010         }
2011
2012         if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
2013                 TALLOC_FREE(result);
2014                 return NT_STATUS_NO_MEMORY;
2015         }
2016
2017         if (!pdb_set_pass_last_set_time(
2018                     sam_account,
2019                     nt_time_to_unix(info->pass_last_set_time),
2020                     PDB_CHANGED)) {
2021                 TALLOC_FREE(result);
2022                 return NT_STATUS_NO_MEMORY;
2023         }
2024
2025         if (!pdb_set_pass_can_change_time(
2026                     sam_account,
2027                     nt_time_to_unix(info->pass_can_change_time),
2028                     PDB_CHANGED)) {
2029                 TALLOC_FREE(result);
2030                 return NT_STATUS_NO_MEMORY;
2031         }
2032
2033         if (!pdb_set_pass_must_change_time(
2034                     sam_account,
2035                     nt_time_to_unix(info->pass_must_change_time),
2036                     PDB_CHANGED)) {
2037                 TALLOC_FREE(result);
2038                 return NT_STATUS_NO_MEMORY;
2039         }
2040
2041         /* save this here to _net_sam_logon() doesn't fail (it assumes a
2042            valid struct samu) */
2043
2044         result->sam_account = sam_account;
2045         result->unix_name = talloc_strdup(result, found_username);
2046
2047         result->sanitized_username = sanitize_username(result,
2048                                                        result->unix_name);
2049         result->login_server = talloc_strdup(result, info->logon_server);
2050
2051         if ((result->unix_name == NULL)
2052             || (result->sanitized_username == NULL)
2053             || (result->login_server == NULL)) {
2054                 TALLOC_FREE(result);
2055                 return NT_STATUS_NO_MEMORY;
2056         }
2057
2058         /* Fill in the unix info we found on the way */
2059
2060         result->utok.uid = uid;
2061         result->utok.gid = gid;
2062
2063         /* Create a 'combined' list of all SIDs we might want in the SD */
2064
2065         result->num_sids = info->num_sids - 2;
2066         result->sids = talloc_array(result, DOM_SID, result->num_sids);
2067         if (result->sids == NULL) {
2068                 TALLOC_FREE(result);
2069                 return NT_STATUS_NO_MEMORY;
2070         }
2071
2072         for (i=0; i < result->num_sids; i++) {
2073                 memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
2074         }
2075
2076         /* Ensure the primary group sid is at position 0. */
2077         sort_sid_array_for_smbd(result, &group_sid);
2078
2079         /* ensure we are never given NULL session keys */
2080
2081         if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
2082                 result->user_session_key = data_blob_null;
2083         } else {
2084                 result->user_session_key = data_blob_talloc(
2085                         result, info->user_session_key,
2086                         sizeof(info->user_session_key));
2087         }
2088
2089         if (memcmp(info->lm_session_key, zeros, 8) == 0) {
2090                 result->lm_session_key = data_blob_null;
2091         } else {
2092                 result->lm_session_key = data_blob_talloc(
2093                         result, info->lm_session_key,
2094                         sizeof(info->lm_session_key));
2095         }
2096
2097         result->nss_token |= username_was_mapped;
2098
2099         *server_info = result;
2100
2101         return NT_STATUS_OK;
2102 }
2103
2104 /***************************************************************************
2105  Free a user_info struct
2106 ***************************************************************************/
2107
2108 void free_user_info(struct auth_usersupplied_info **user_info)
2109 {
2110         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
2111         if (*user_info != NULL) {
2112                 if ((*user_info)->smb_name) {
2113                         DEBUG(10,("structure was created for %s\n",
2114                                   (*user_info)->smb_name));
2115                 }
2116                 SAFE_FREE((*user_info)->smb_name);
2117                 SAFE_FREE((*user_info)->internal_username);
2118                 SAFE_FREE((*user_info)->client_domain);
2119                 SAFE_FREE((*user_info)->domain);
2120                 SAFE_FREE((*user_info)->wksta_name);
2121                 data_blob_free(&(*user_info)->lm_resp);
2122                 data_blob_free(&(*user_info)->nt_resp);
2123                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
2124                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
2125                 data_blob_clear_free(&(*user_info)->plaintext_password);
2126                 ZERO_STRUCT(**user_info);
2127         }
2128         SAFE_FREE(*user_info);
2129 }
2130
2131 /***************************************************************************
2132  Make an auth_methods struct
2133 ***************************************************************************/
2134
2135 bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
2136 {
2137         if (!auth_context) {
2138                 smb_panic("no auth_context supplied to "
2139                           "make_auth_methods()!\n");
2140         }
2141
2142         if (!auth_method) {
2143                 smb_panic("make_auth_methods: pointer to auth_method pointer "
2144                           "is NULL!\n");
2145         }
2146
2147         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
2148         if (!*auth_method) {
2149                 DEBUG(0,("make_auth_method: malloc failed!\n"));
2150                 return False;
2151         }
2152         ZERO_STRUCTP(*auth_method);
2153
2154         return True;
2155 }
2156
2157 /**
2158  * Verify whether or not given domain is trusted.
2159  *
2160  * @param domain_name name of the domain to be verified
2161  * @return true if domain is one of the trusted ones or
2162  *         false if otherwise
2163  **/
2164
2165 bool is_trusted_domain(const char* dom_name)
2166 {
2167         DOM_SID trustdom_sid;
2168         bool ret;
2169
2170         /* no trusted domains for a standalone server */
2171
2172         if ( lp_server_role() == ROLE_STANDALONE )
2173                 return False;
2174
2175         if (dom_name == NULL || dom_name[0] == '\0') {
2176                 return false;
2177         }
2178
2179         if (strequal(dom_name, get_global_sam_name())) {
2180                 return false;
2181         }
2182
2183         /* if we are a DC, then check for a direct trust relationships */
2184
2185         if ( IS_DC ) {
2186                 become_root();
2187                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2188                           "[%s]\n", dom_name ));
2189                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2190                 unbecome_root();
2191                 if (ret)
2192                         return True;
2193         }
2194         else {
2195                 wbcErr result;
2196
2197                 /* If winbind is around, ask it */
2198
2199                 result = wb_is_trusted_domain(dom_name);
2200
2201                 if (result == WBC_ERR_SUCCESS) {
2202                         return True;
2203                 }
2204
2205                 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
2206                         /* winbind could not find the domain */
2207                         return False;
2208                 }
2209
2210                 /* The only other possible result is that winbind is not up
2211                    and running. We need to update the trustdom_cache
2212                    ourselves */
2213
2214                 update_trustdom_cache();
2215         }
2216
2217         /* now the trustdom cache should be available a DC could still
2218          * have a transitive trust so fall back to the cache of trusted
2219          * domains (like a domain member would use  */
2220
2221         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
2222                 return True;
2223         }
2224
2225         return False;
2226 }
2227