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