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