5bb5a69dfa7c808677e588a20694feb9d3bff607
[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
637         add_sid_to_array_unique(session_info->security_token, &tmp_sid,
638                                 &session_info->security_token->sids,
639                                 &session_info->security_token->num_sids);
640
641         for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
642                 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
643                 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
644                                         &session_info->security_token->sids,
645                                         &session_info->security_token->num_sids);
646         }
647
648         security_token_debug(DBGC_AUTH, 10, session_info->security_token);
649         debug_unix_user_token(DBGC_AUTH, 10,
650                               session_info->unix_token->uid,
651                               session_info->unix_token->gid,
652                               session_info->unix_token->ngroups,
653                               session_info->unix_token->groups);
654
655         status = log_nt_token(session_info->security_token);
656         if (!NT_STATUS_IS_OK(status)) {
657                 return status;
658         }
659
660         *session_info_out = session_info;
661         return NT_STATUS_OK;
662 }
663
664 /***************************************************************************
665  Make (and fill) a server_info struct from a 'struct passwd' by conversion
666  to a struct samu
667 ***************************************************************************/
668
669 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
670                              const char *unix_username,
671                              const struct passwd *pwd,
672                              struct auth_serversupplied_info **server_info)
673 {
674         NTSTATUS status;
675         TALLOC_CTX *tmp_ctx = NULL;
676         struct auth_serversupplied_info *result;
677
678         tmp_ctx = talloc_stackframe();
679         if (tmp_ctx == NULL) {
680                 return NT_STATUS_NO_MEMORY;
681         }
682
683         result = make_server_info(tmp_ctx);
684         if (result == NULL) {
685                 status = NT_STATUS_NO_MEMORY;
686                 goto done;
687         }
688
689         status = passwd_to_SamInfo3(result,
690                                     unix_username,
691                                     pwd,
692                                     &result->info3,
693                                     &result->extra);
694         if (!NT_STATUS_IS_OK(status)) {
695                 goto done;
696         }
697
698         result->unix_name = talloc_strdup(result, unix_username);
699         if (result->unix_name == NULL) {
700                 status = NT_STATUS_NO_MEMORY;
701                 goto done;
702         }
703
704         result->utok.uid = pwd->pw_uid;
705         result->utok.gid = pwd->pw_gid;
706
707         *server_info = talloc_steal(mem_ctx, result);
708         status = NT_STATUS_OK;
709 done:
710         talloc_free(tmp_ctx);
711
712         return status;
713 }
714
715 static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx,
716                                  struct netr_SamInfo3 *info3)
717 {
718         NTSTATUS status;
719
720         /* Set account name */
721         init_lsa_String(&info3->base.account_name, "SYSTEM");
722
723         /* Set domain name */
724         init_lsa_StringLarge(&info3->base.logon_domain, "NT AUTHORITY");
725
726
727         status = dom_sid_split_rid(mem_ctx, &global_sid_System,
728                                    &info3->base.domain_sid,
729                                    &info3->base.rid);
730         if (!NT_STATUS_IS_OK(status)) {
731                 return status;
732         }
733
734         /* Primary gid is the same */
735         info3->base.primary_gid = info3->base.rid;
736
737         return NT_STATUS_OK;
738 }
739
740 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
741                                 struct netr_SamInfo3 *info3)
742 {
743         const char *guest_account = lp_guest_account();
744         struct dom_sid domain_sid;
745         struct passwd *pwd;
746         const char *tmp;
747
748         pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
749         if (pwd == NULL) {
750                 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
751                          "account [%s]!\n", guest_account));
752                 return NT_STATUS_NO_SUCH_USER;
753         }
754
755         /* Set account name */
756         tmp = talloc_strdup(mem_ctx, pwd->pw_name);
757         if (tmp == NULL) {
758                 return NT_STATUS_NO_MEMORY;
759         }
760         init_lsa_String(&info3->base.account_name, tmp);
761
762         /* Set domain name */
763         tmp = talloc_strdup(mem_ctx, get_global_sam_name());
764         if (tmp == NULL) {
765                 return NT_STATUS_NO_MEMORY;
766         }
767         init_lsa_StringLarge(&info3->base.logon_domain, tmp);
768
769         /* Domain sid */
770         sid_copy(&domain_sid, get_global_sam_sid());
771
772         info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
773         if (info3->base.domain_sid == NULL) {
774                 return NT_STATUS_NO_MEMORY;
775         }
776
777         /* Guest rid */
778         info3->base.rid = DOMAIN_RID_GUEST;
779
780         /* Primary gid */
781         info3->base.primary_gid = DOMAIN_RID_GUESTS;
782
783         /* Set as guest */
784         info3->base.user_flags = NETLOGON_GUEST;
785
786         TALLOC_FREE(pwd);
787         return NT_STATUS_OK;
788 }
789
790 /***************************************************************************
791  Make (and fill) a user_info struct for a guest login.
792  This *must* succeed for smbd to start. If there is no mapping entry for
793  the guest gid, then create one.
794
795  The resulting structure is a 'session_info' because
796  create_local_token() has already been called on it.  This is quite
797  nasty, as the auth subsystem isn't expect this, but the behavior is
798  left as-is for now.
799 ***************************************************************************/
800
801 static NTSTATUS make_new_session_info_guest(struct auth_session_info **session_info, struct auth_serversupplied_info **server_info)
802 {
803         const char *guest_account = lp_guest_account();
804         const char *domain = lp_netbios_name();
805         struct netr_SamInfo3 info3;
806         TALLOC_CTX *tmp_ctx;
807         NTSTATUS status;
808
809         tmp_ctx = talloc_stackframe();
810         if (tmp_ctx == NULL) {
811                 return NT_STATUS_NO_MEMORY;
812         }
813
814         ZERO_STRUCT(info3);
815
816         status = get_guest_info3(tmp_ctx, &info3);
817         if (!NT_STATUS_IS_OK(status)) {
818                 DEBUG(0, ("get_guest_info3 failed with %s\n",
819                           nt_errstr(status)));
820                 goto done;
821         }
822
823         status = make_server_info_info3(tmp_ctx,
824                                         guest_account,
825                                         domain,
826                                         server_info,
827                                         &info3);
828         if (!NT_STATUS_IS_OK(status)) {
829                 DEBUG(0, ("make_server_info_info3 failed with %s\n",
830                           nt_errstr(status)));
831                 goto done;
832         }
833
834         (*server_info)->guest = true;
835
836         /* This should not be done here (we should produce a server
837          * info, and later construct a session info from it), but for
838          * now this does not change the previous behavior */
839         status = create_local_token(tmp_ctx, *server_info, NULL,
840                                     (*server_info)->info3->base.account_name.string,
841                                     session_info);
842         if (!NT_STATUS_IS_OK(status)) {
843                 DEBUG(0, ("create_local_token failed: %s\n",
844                           nt_errstr(status)));
845                 goto done;
846         }
847         talloc_steal(NULL, *session_info);
848         talloc_steal(NULL, *server_info);
849
850         /* annoying, but the Guest really does have a session key, and it is
851            all zeros! */
852         (*session_info)->session_key = data_blob_talloc_zero(NULL, 16);
853
854         status = NT_STATUS_OK;
855 done:
856         TALLOC_FREE(tmp_ctx);
857         return status;
858 }
859
860 /***************************************************************************
861  Make (and fill) a auth_session_info struct for a system user login.
862  This *must* succeed for smbd to start.
863 ***************************************************************************/
864
865 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
866                                             struct auth_session_info **session_info)
867 {
868         NTSTATUS status;
869         struct auth_serversupplied_info *server_info;
870         TALLOC_CTX *tmp_ctx;
871
872         tmp_ctx = talloc_stackframe();
873         if (tmp_ctx == NULL) {
874                 return NT_STATUS_NO_MEMORY;
875         }
876
877         server_info = make_server_info(tmp_ctx);
878         if (!server_info) {
879                 status = NT_STATUS_NO_MEMORY;
880                 DEBUG(0, ("failed making server_info\n"));
881                 goto done;
882         }
883
884         server_info->info3 = talloc_zero(server_info, struct netr_SamInfo3);
885         if (!server_info->info3) {
886                 status = NT_STATUS_NO_MEMORY;
887                 DEBUG(0, ("talloc failed setting info3\n"));
888                 goto done;
889         }
890
891         status = get_system_info3(server_info, server_info->info3);
892         if (!NT_STATUS_IS_OK(status)) {
893                 DEBUG(0, ("Failed creating system info3 with %s\n",
894                           nt_errstr(status)));
895                 goto done;
896         }
897
898         server_info->utok.uid = sec_initial_uid();
899         server_info->utok.gid = sec_initial_gid();
900         server_info->unix_name = talloc_asprintf(server_info,
901                                                  "NT AUTHORITY%cSYSTEM",
902                                                  *lp_winbind_separator());
903
904         if (!server_info->unix_name) {
905                 status = NT_STATUS_NO_MEMORY;
906                 DEBUG(0, ("talloc_asprintf failed setting unix_name\n"));
907                 goto done;
908         }
909
910         server_info->security_token = talloc_zero(server_info, struct security_token);
911         if (!server_info->security_token) {
912                 status = NT_STATUS_NO_MEMORY;
913                 DEBUG(0, ("talloc failed setting security token\n"));
914                 goto done;
915         }
916
917         status = add_sid_to_array_unique(server_info->security_token->sids,
918                                          &global_sid_System,
919                                          &server_info->security_token->sids,
920                                          &server_info->security_token->num_sids);
921         if (!NT_STATUS_IS_OK(status)) {
922                 goto done;
923         }
924
925         /* SYSTEM has all privilages */
926         server_info->security_token->privilege_mask = ~0;
927
928         /* Now turn the server_info into a session_info with the full token etc */
929         status = create_local_token(mem_ctx, server_info, NULL, "SYSTEM", session_info);
930         talloc_free(server_info);
931
932         if (!NT_STATUS_IS_OK(status)) {
933                 DEBUG(0, ("create_local_token failed: %s\n",
934                           nt_errstr(status)));
935                 goto done;
936         }
937
938         talloc_steal(mem_ctx, *session_info);
939
940 done:
941         TALLOC_FREE(tmp_ctx);
942         return status;
943 }
944
945 /****************************************************************************
946   Fake a auth_session_info just from a username (as a
947   session_info structure, with create_local_token() already called on
948   it.
949 ****************************************************************************/
950
951 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
952                                          const char *username,
953                                          bool is_guest,
954                                          struct auth_session_info **session_info)
955 {
956         struct passwd *pwd;
957         NTSTATUS status;
958         struct auth_serversupplied_info *result;
959         TALLOC_CTX *tmp_ctx;
960
961         tmp_ctx = talloc_stackframe();
962         if (tmp_ctx == NULL) {
963                 return NT_STATUS_NO_MEMORY;
964         }
965
966         pwd = Get_Pwnam_alloc(tmp_ctx, username);
967         if (pwd == NULL) {
968                 status = NT_STATUS_NO_SUCH_USER;
969                 goto done;
970         }
971
972         status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
973         if (!NT_STATUS_IS_OK(status)) {
974                 goto done;
975         }
976
977         result->nss_token = true;
978         result->guest = is_guest;
979
980         /* Now turn the server_info into a session_info with the full token etc */
981         status = create_local_token(mem_ctx,
982                                     result,
983                                     NULL,
984                                     pwd->pw_name,
985                                     session_info);
986
987 done:
988         talloc_free(tmp_ctx);
989
990         return status;
991 }
992
993 /* This function MUST only used to create the cached server_info for
994  * guest.
995  *
996  * This is a lossy conversion.  Variables known to be lost so far
997  * include:
998  *
999  * - nss_token (not needed because the only read doesn't happen
1000  * for the GUEST user, as this routine populates ->security_token
1001  *
1002  * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1003  *
1004  * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1005  */
1006 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1007                                                                            const struct auth_session_info *src,
1008                                                                            struct auth_serversupplied_info *server_info)
1009 {
1010         struct auth_serversupplied_info *dst;
1011
1012         dst = make_server_info(mem_ctx);
1013         if (dst == NULL) {
1014                 return NULL;
1015         }
1016
1017         /* This element must be provided to convert back to an auth_serversupplied_info */
1018         SMB_ASSERT(src->unix_info);
1019
1020         dst->guest = true;
1021         dst->system = false;
1022
1023         /* This element must be provided to convert back to an
1024          * auth_serversupplied_info.  This needs to be from the
1025          * auth_session_info because the group values in particular
1026          * may change during create_local_token() processing */
1027         SMB_ASSERT(src->unix_token);
1028         dst->utok.uid = src->unix_token->uid;
1029         dst->utok.gid = src->unix_token->gid;
1030         dst->utok.ngroups = src->unix_token->ngroups;
1031         if (src->unix_token->ngroups != 0) {
1032                 dst->utok.groups = (gid_t *)talloc_memdup(
1033                         dst, src->unix_token->groups,
1034                         sizeof(gid_t)*dst->utok.ngroups);
1035         } else {
1036                 dst->utok.groups = NULL;
1037         }
1038
1039         /* We must have a security_token as otherwise the lossy
1040          * conversion without nss_token would cause create_local_token
1041          * to take the wrong path */
1042         SMB_ASSERT(src->security_token);
1043
1044         dst->security_token = dup_nt_token(dst, src->security_token);
1045         if (!dst->security_token) {
1046                 TALLOC_FREE(dst);
1047                 return NULL;
1048         }
1049
1050         dst->session_key = data_blob_talloc( dst, src->session_key.data,
1051                                                 src->session_key.length);
1052
1053         /* This is OK because this functions is only used for the
1054          * GUEST account, which has all-zero keys for both values */
1055         dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1056                                                 src->session_key.length);
1057
1058         dst->info3 = copy_netr_SamInfo3(dst, server_info->info3);
1059         if (!dst->info3) {
1060                 TALLOC_FREE(dst);
1061                 return NULL;
1062         }
1063
1064         dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1065         if (!dst->unix_name) {
1066                 TALLOC_FREE(dst);
1067                 return NULL;
1068         }
1069
1070         return dst;
1071 }
1072
1073 struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1074                                              const struct auth_session_info *src)
1075 {
1076         struct auth_session_info *dst;
1077         DATA_BLOB blob;
1078         enum ndr_err_code ndr_err;
1079
1080         ndr_err = ndr_push_struct_blob(
1081                 &blob, talloc_tos(), src,
1082                 (ndr_push_flags_fn_t)ndr_push_auth_session_info);
1083         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1084                 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1085                            "%s\n", ndr_errstr(ndr_err)));
1086                 return NULL;
1087         }
1088
1089         dst = talloc(mem_ctx, struct auth_session_info);
1090         if (dst == NULL) {
1091                 DEBUG(0, ("talloc failed\n"));
1092                 TALLOC_FREE(blob.data);
1093                 return NULL;
1094         }
1095
1096         ndr_err = ndr_pull_struct_blob(
1097                 &blob, dst, dst,
1098                 (ndr_pull_flags_fn_t)ndr_pull_auth_session_info);
1099         TALLOC_FREE(blob.data);
1100
1101         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1102                 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1103                            "%s\n", ndr_errstr(ndr_err)));
1104                 TALLOC_FREE(dst);
1105                 return NULL;
1106         }
1107
1108         return dst;
1109 }
1110
1111 /*
1112  * Set a new session key. Used in the rpc server where we have to override the
1113  * SMB level session key with SystemLibraryDTC
1114  */
1115
1116 bool session_info_set_session_key(struct auth_session_info *info,
1117                                  DATA_BLOB session_key)
1118 {
1119         TALLOC_FREE(info->session_key.data);
1120
1121         info->session_key = data_blob_talloc(
1122                 info, session_key.data, session_key.length);
1123
1124         return (info->session_key.data != NULL);
1125 }
1126
1127 static struct auth_session_info *guest_info = NULL;
1128
1129 static struct auth_serversupplied_info *guest_server_info = NULL;
1130
1131 bool init_guest_info(void)
1132 {
1133         if (guest_info != NULL)
1134                 return true;
1135
1136         return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info, &guest_server_info));
1137 }
1138
1139 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1140                                 struct auth_serversupplied_info **server_info)
1141 {
1142         /* This is trickier than it would appear to need to be because
1143          * we are trying to avoid certain costly operations when the
1144          * structure is converted to a 'auth_session_info' again in
1145          * create_local_token() */
1146         *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1147         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1148 }
1149
1150 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1151                                 struct auth_session_info **session_info)
1152 {
1153         *session_info = copy_session_info(mem_ctx, guest_info);
1154         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1155 }
1156
1157 static struct auth_session_info *system_info = NULL;
1158
1159 NTSTATUS init_system_session_info(void)
1160 {
1161         if (system_info != NULL)
1162                 return NT_STATUS_OK;
1163
1164         return make_new_session_info_system(NULL, &system_info);
1165 }
1166
1167 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1168                                 struct auth_session_info **session_info)
1169 {
1170         if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1171         *session_info = copy_session_info(mem_ctx, system_info);
1172         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1173 }
1174
1175 const struct auth_session_info *get_session_info_system(void)
1176 {
1177     return system_info;
1178 }
1179
1180 /***************************************************************************
1181  Purely internal function for make_server_info_info3
1182 ***************************************************************************/
1183
1184 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1185                               const char *username, char **found_username,
1186                               struct passwd **pwd,
1187                               bool *username_was_mapped)
1188 {
1189         char *orig_dom_user = NULL;
1190         char *dom_user = NULL;
1191         char *lower_username = NULL;
1192         char *real_username = NULL;
1193         struct passwd *passwd;
1194
1195         lower_username = talloc_strdup(mem_ctx, username);
1196         if (!lower_username) {
1197                 return NT_STATUS_NO_MEMORY;
1198         }
1199         if (!strlower_m( lower_username )) {
1200                 return NT_STATUS_INVALID_PARAMETER;
1201         }
1202
1203         orig_dom_user = talloc_asprintf(mem_ctx,
1204                                 "%s%c%s",
1205                                 domain,
1206                                 *lp_winbind_separator(),
1207                                 lower_username);
1208         if (!orig_dom_user) {
1209                 return NT_STATUS_NO_MEMORY;
1210         }
1211
1212         /* Get the passwd struct.  Try to create the account if necessary. */
1213
1214         *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1215         if (!dom_user) {
1216                 return NT_STATUS_NO_MEMORY;
1217         }
1218
1219         passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
1220         if (!passwd) {
1221                 DEBUG(3, ("Failed to find authenticated user %s via "
1222                           "getpwnam(), denying access.\n", dom_user));
1223                 return NT_STATUS_NO_SUCH_USER;
1224         }
1225
1226         if (!real_username) {
1227                 return NT_STATUS_NO_MEMORY;
1228         }
1229
1230         *pwd = passwd;
1231
1232         /* This is pointless -- there is no support for differing
1233            unix and windows names.  Make sure to always store the 
1234            one we actually looked up and succeeded. Have I mentioned
1235            why I hate the 'winbind use default domain' parameter?   
1236                                          --jerry              */
1237
1238         *found_username = talloc_strdup( mem_ctx, real_username );
1239
1240         return NT_STATUS_OK;
1241 }
1242
1243 /****************************************************************************
1244  Wrapper to allow the getpwnam() call to strip the domain name and 
1245  try again in case a local UNIX user is already there.  Also run through 
1246  the username if we fallback to the username only.
1247  ****************************************************************************/
1248
1249 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1250                              char **p_save_username, bool create )
1251 {
1252         struct passwd *pw = NULL;
1253         char *p = NULL;
1254         char *username = NULL;
1255
1256         /* we only save a copy of the username it has been mangled 
1257            by winbindd use default domain */
1258         *p_save_username = NULL;
1259
1260         /* don't call map_username() here since it has to be done higher 
1261            up the stack so we don't call it multiple times */
1262
1263         username = talloc_strdup(mem_ctx, domuser);
1264         if (!username) {
1265                 return NULL;
1266         }
1267
1268         p = strchr_m( username, *lp_winbind_separator() );
1269
1270         /* code for a DOMAIN\user string */
1271
1272         if ( p ) {
1273                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1274                 if ( pw ) {
1275                         /* make sure we get the case of the username correct */
1276                         /* work around 'winbind use default domain = yes' */
1277
1278                         if ( lp_winbind_use_default_domain() &&
1279                              !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1280                                 char *domain;
1281
1282                                 /* split the domain and username into 2 strings */
1283                                 *p = '\0';
1284                                 domain = username;
1285
1286                                 *p_save_username = talloc_asprintf(mem_ctx,
1287                                                                 "%s%c%s",
1288                                                                 domain,
1289                                                                 *lp_winbind_separator(),
1290                                                                 pw->pw_name);
1291                                 if (!*p_save_username) {
1292                                         TALLOC_FREE(pw);
1293                                         return NULL;
1294                                 }
1295                         } else {
1296                                 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1297                         }
1298
1299                         /* whew -- done! */
1300                         return pw;
1301                 }
1302
1303                 /* setup for lookup of just the username */
1304                 /* remember that p and username are overlapping memory */
1305
1306                 p++;
1307                 username = talloc_strdup(mem_ctx, p);
1308                 if (!username) {
1309                         return NULL;
1310                 }
1311         }
1312
1313         /* just lookup a plain username */
1314
1315         pw = Get_Pwnam_alloc(mem_ctx, username);
1316
1317         /* Create local user if requested but only if winbindd
1318            is not running.  We need to protect against cases
1319            where winbindd is failing and then prematurely
1320            creating users in /etc/passwd */
1321
1322         if ( !pw && create && !winbind_ping() ) {
1323                 /* Don't add a machine account. */
1324                 if (username[strlen(username)-1] == '$')
1325                         return NULL;
1326
1327                 _smb_create_user(NULL, username, NULL);
1328                 pw = Get_Pwnam_alloc(mem_ctx, username);
1329         }
1330
1331         /* one last check for a valid passwd struct */
1332
1333         if (pw) {
1334                 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1335         }
1336         return pw;
1337 }
1338
1339 /***************************************************************************
1340  Make a server_info struct from the info3 returned by a domain logon 
1341 ***************************************************************************/
1342
1343 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1344                                 const char *sent_nt_username,
1345                                 const char *domain,
1346                                 struct auth_serversupplied_info **server_info,
1347                                 const struct netr_SamInfo3 *info3)
1348 {
1349         NTSTATUS nt_status = NT_STATUS_OK;
1350         char *found_username = NULL;
1351         const char *nt_domain;
1352         const char *nt_username;
1353         struct dom_sid user_sid;
1354         struct dom_sid group_sid;
1355         bool username_was_mapped;
1356         struct passwd *pwd;
1357         struct auth_serversupplied_info *result;
1358         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1359
1360         /* 
1361            Here is where we should check the list of
1362            trusted domains, and verify that the SID 
1363            matches.
1364         */
1365
1366         if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
1367                 nt_status = NT_STATUS_INVALID_PARAMETER;
1368                 goto out;
1369         }
1370
1371         if (!sid_compose(&group_sid, info3->base.domain_sid,
1372                          info3->base.primary_gid)) {
1373                 nt_status = NT_STATUS_INVALID_PARAMETER;
1374                 goto out;
1375         }
1376
1377         nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
1378         if (!nt_username) {
1379                 /* If the server didn't give us one, just use the one we sent
1380                  * them */
1381                 nt_username = sent_nt_username;
1382         }
1383
1384         nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
1385         if (!nt_domain) {
1386                 /* If the server didn't give us one, just use the one we sent
1387                  * them */
1388                 nt_domain = domain;
1389         }
1390
1391         /* If getpwnam() fails try the add user script (2.2.x behavior).
1392
1393            We use the _unmapped_ username here in an attempt to provide
1394            consistent username mapping behavior between kerberos and NTLM[SSP]
1395            authentication in domain mode security.  I.E. Username mapping
1396            should be applied to the fully qualified username
1397            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1398            called map_username() unnecessarily in make_user_info_map() but
1399            that is how the current code is designed.  Making the change here
1400            is the least disruptive place.  -- jerry */
1401
1402         /* this call will try to create the user if necessary */
1403
1404         nt_status = check_account(tmp_ctx,
1405                                   nt_domain,
1406                                   nt_username,
1407                                   &found_username,
1408                                   &pwd,
1409                                   &username_was_mapped);
1410
1411         if (!NT_STATUS_IS_OK(nt_status)) {
1412                 /* Handle 'map to guest = Bad Uid */
1413                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
1414                     (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
1415                     lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
1416                         DBG_NOTICE("Try to map %s to guest account",
1417                                    nt_username);
1418                         nt_status = make_server_info_guest(tmp_ctx, &result);
1419                         if (NT_STATUS_IS_OK(nt_status)) {
1420                                 *server_info = talloc_move(mem_ctx, &result);
1421                         }
1422                 }
1423                 goto out;
1424         }
1425
1426         result = make_server_info(tmp_ctx);
1427         if (result == NULL) {
1428                 DEBUG(4, ("make_server_info failed!\n"));
1429                 nt_status = NT_STATUS_NO_MEMORY;
1430                 goto out;
1431         }
1432
1433         result->unix_name = talloc_strdup(result, found_username);
1434
1435         /* copy in the info3 */
1436         result->info3 = copy_netr_SamInfo3(result, info3);
1437         if (result->info3 == NULL) {
1438                 nt_status = NT_STATUS_NO_MEMORY;
1439                 goto out;
1440         }
1441
1442         /* Fill in the unix info we found on the way */
1443
1444         result->utok.uid = pwd->pw_uid;
1445         result->utok.gid = pwd->pw_gid;
1446
1447         /* ensure we are never given NULL session keys */
1448
1449         if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
1450                 result->session_key = data_blob_null;
1451         } else {
1452                 result->session_key = data_blob_talloc(
1453                         result, info3->base.key.key,
1454                         sizeof(info3->base.key.key));
1455         }
1456
1457         if (all_zero(info3->base.LMSessKey.key,
1458                      sizeof(info3->base.LMSessKey.key))) {
1459                 result->lm_session_key = data_blob_null;
1460         } else {
1461                 result->lm_session_key = data_blob_talloc(
1462                         result, info3->base.LMSessKey.key,
1463                         sizeof(info3->base.LMSessKey.key));
1464         }
1465
1466         result->nss_token |= username_was_mapped;
1467
1468         result->guest = (info3->base.user_flags & NETLOGON_GUEST);
1469
1470         *server_info = talloc_move(mem_ctx, &result);
1471
1472         nt_status = NT_STATUS_OK;
1473 out:
1474         talloc_free(tmp_ctx);
1475
1476         return nt_status;
1477 }
1478
1479 /*****************************************************************************
1480  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1481 ******************************************************************************/
1482
1483 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1484                                           const char *sent_nt_username,
1485                                           const char *domain,
1486                                           const struct wbcAuthUserInfo *info,
1487                                           struct auth_serversupplied_info **server_info)
1488 {
1489         struct netr_SamInfo3 info3;
1490         struct netr_SamInfo6 *info6;
1491
1492         info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
1493         if (!info6) {
1494                 return NT_STATUS_NO_MEMORY;
1495         }
1496
1497         info3.base = info6->base;
1498         info3.sidcount = info6->sidcount;
1499         info3.sids = info6->sids;
1500
1501         return make_server_info_info3(mem_ctx,
1502                                       sent_nt_username, domain,
1503                                       server_info, &info3);
1504 }
1505
1506 /**
1507  * Verify whether or not given domain is trusted.
1508  *
1509  * This should only be used on a DC.
1510  *
1511  * @param domain_name name of the domain to be verified
1512  * @return true if domain is one of the trusted ones or
1513  *         false if otherwise
1514  **/
1515
1516 bool is_trusted_domain(const char* dom_name)
1517 {
1518         bool ret;
1519
1520         if (!IS_DC) {
1521                 return false;
1522         }
1523
1524         if (dom_name == NULL || dom_name[0] == '\0') {
1525                 return false;
1526         }
1527
1528         if (strequal(dom_name, get_global_sam_name())) {
1529                 return false;
1530         }
1531
1532         become_root();
1533         DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1534                   "[%s]\n", dom_name ));
1535         ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1536         unbecome_root();
1537
1538         return ret;
1539 }
1540
1541
1542
1543 /*
1544   on a logon error possibly map the error to success if "map to guest"
1545   is set approriately
1546 */
1547 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
1548                                      NTSTATUS status,
1549                                      const char *user,
1550                                      const char *domain,
1551                                      struct auth_serversupplied_info **server_info)
1552 {
1553         user = user ? user : "";
1554         domain = domain ? domain : "";
1555
1556         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1557                 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
1558                     (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
1559                         DEBUG(3,("No such user %s [%s] - using guest account\n",
1560                                  user, domain));
1561                         return make_server_info_guest(mem_ctx, server_info);
1562                 }
1563         } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1564                 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
1565                         DEBUG(3,("Registered username %s for guest access\n",
1566                                 user));
1567                         return make_server_info_guest(mem_ctx, server_info);
1568                 }
1569         }
1570
1571         return status;
1572 }
1573
1574 /*
1575   Extract session key from a session info and return it in a blob
1576   if intent is KEY_USE_16BYTES, truncate it to 16 bytes
1577
1578   See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
1579   Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
1580
1581   Note that returned session_key is referencing the original key, it is supposed to be
1582   short-lived. If original session_info->session_key is gone, the reference will be broken.
1583 */
1584 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
1585 {
1586
1587         if (session_key == NULL || session_info == NULL) {
1588                 return NT_STATUS_INVALID_PARAMETER;
1589         }
1590
1591         if (session_info->session_key.length == 0) {
1592                 return NT_STATUS_NO_USER_SESSION_KEY;
1593         }
1594
1595         *session_key = session_info->session_key;
1596         if (intent == KEY_USE_16BYTES) {
1597                 session_key->length = MIN(session_info->session_key.length, 16);
1598         }
1599         return NT_STATUS_OK;
1600 }