s4:kdc: Implement KDC plugin hardware authentication policy
[samba.git] / source3 / auth / auth_util.c
1 /*
2    Unix SMB/CIFS implementation.
3    Authentication utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Andrew Bartlett 2001-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 "dom_sid.h"
25 #include "includes.h"
26 #include "auth.h"
27 #include "lib/util_unixsids.h"
28 #include "../libcli/auth/libcli_auth.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 #include "source4/auth/auth.h"
41 #include "auth/auth_util.h"
42 #include "source3/lib/substitute.h"
43
44 #undef DBGC_CLASS
45 #define DBGC_CLASS DBGC_AUTH
46
47 /****************************************************************************
48  Create a UNIX user on demand.
49 ****************************************************************************/
50
51 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
52 {
53         TALLOC_CTX *ctx = talloc_tos();
54         const struct loadparm_substitution *lp_sub =
55                 loadparm_s3_global_substitution();
56         char *add_script;
57         int ret;
58
59         add_script = lp_add_user_script(ctx, lp_sub);
60         if (!add_script || !*add_script) {
61                 return -1;
62         }
63         add_script = talloc_all_string_sub(ctx,
64                                 add_script,
65                                 "%u",
66                                 unix_username);
67         if (!add_script) {
68                 return -1;
69         }
70         if (domain) {
71                 add_script = talloc_all_string_sub(ctx,
72                                         add_script,
73                                         "%D",
74                                         domain);
75                 if (!add_script) {
76                         return -1;
77                 }
78         }
79         if (homedir) {
80                 add_script = talloc_all_string_sub(ctx,
81                                 add_script,
82                                 "%H",
83                                 homedir);
84                 if (!add_script) {
85                         return -1;
86                 }
87         }
88         ret = smbrun(add_script, NULL, NULL);
89         flush_pwnam_cache();
90         DEBUG(ret ? 0 : 3,
91                 ("smb_create_user: Running the command `%s' gave %d\n",
92                  add_script,ret));
93         return ret;
94 }
95
96 /****************************************************************************
97  Create an auth_usersupplied_data structure after appropriate mapping.
98 ****************************************************************************/
99
100 NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
101                             struct auth_usersupplied_info **user_info,
102                             const char *smb_name,
103                             const char *client_domain,
104                             const char *workstation_name,
105                             const struct tsocket_address *remote_address,
106                             const struct tsocket_address *local_address,
107                             const char *service_description,
108                             const DATA_BLOB *lm_pwd,
109                             const DATA_BLOB *nt_pwd,
110                             const struct samr_Password *lm_interactive_pwd,
111                             const struct samr_Password *nt_interactive_pwd,
112                             const char *plaintext,
113                             enum auth_password_state password_state)
114 {
115         const char *domain;
116         NTSTATUS result;
117         bool was_mapped;
118         char *internal_username = NULL;
119
120         was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
121         if (!internal_username) {
122                 return NT_STATUS_NO_MEMORY;
123         }
124
125         DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
126                  client_domain, smb_name, workstation_name));
127
128         /*
129          * We let the auth stack canonicalize, username
130          * and domain.
131          */
132         domain = client_domain;
133
134         result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
135                                 client_domain, domain, workstation_name,
136                                 remote_address, local_address,
137                                 service_description, lm_pwd, nt_pwd,
138                                 lm_interactive_pwd, nt_interactive_pwd,
139                                 plaintext, password_state);
140         if (NT_STATUS_IS_OK(result)) {
141                 /* did we actually map the user to a different name? */
142                 (*user_info)->was_mapped = was_mapped;
143         }
144         return result;
145 }
146
147 /****************************************************************************
148  Create an auth_usersupplied_data, making the DATA_BLOBs here.
149  Decrypt and encrypt the passwords.
150 ****************************************************************************/
151
152 bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
153                                      struct auth_usersupplied_info **user_info,
154                                      const char *smb_name,
155                                      const char *client_domain,
156                                      const char *workstation_name,
157                                      const struct tsocket_address *remote_address,
158                                      const struct tsocket_address *local_address,
159                                      uint32_t logon_parameters,
160                                      const uchar *lm_network_pwd,
161                                      int lm_pwd_len,
162                                      const uchar *nt_network_pwd,
163                                      int nt_pwd_len)
164 {
165         bool ret;
166         NTSTATUS status;
167         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
168         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
169
170         status = make_user_info_map(mem_ctx, user_info,
171                                     smb_name, client_domain,
172                                     workstation_name,
173                                     remote_address,
174                                     local_address,
175                                     "SamLogon",
176                                     lm_pwd_len ? &lm_blob : NULL,
177                                     nt_pwd_len ? &nt_blob : NULL,
178                                     NULL, NULL, NULL,
179                                     AUTH_PASSWORD_RESPONSE);
180
181         if (NT_STATUS_IS_OK(status)) {
182                 (*user_info)->logon_parameters = logon_parameters;
183         }
184         ret = NT_STATUS_IS_OK(status) ? true : false;
185
186         data_blob_free(&lm_blob);
187         data_blob_free(&nt_blob);
188         return ret;
189 }
190
191 /****************************************************************************
192  Create an auth_usersupplied_data, making the DATA_BLOBs here.
193  Decrypt and encrypt the passwords.
194 ****************************************************************************/
195
196 bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
197                                          struct auth_usersupplied_info **user_info,
198                                          const char *smb_name,
199                                          const char *client_domain,
200                                          const char *workstation_name,
201                                          const struct tsocket_address *remote_address,
202                                          const struct tsocket_address *local_address,
203                                          uint32_t logon_parameters,
204                                          const uchar chal[8],
205                                          const uchar lm_interactive_pwd[16],
206                                          const uchar nt_interactive_pwd[16])
207 {
208         struct samr_Password lm_pwd;
209         struct samr_Password nt_pwd;
210         unsigned char local_lm_response[24];
211         unsigned char local_nt_response[24];
212         int rc;
213
214         if (lm_interactive_pwd)
215                 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
216
217         if (nt_interactive_pwd)
218                 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
219
220         if (lm_interactive_pwd) {
221                 rc = SMBOWFencrypt(lm_pwd.hash, chal,
222                                    local_lm_response);
223                 if (rc != 0) {
224                         return false;
225                 }
226         }
227
228         if (nt_interactive_pwd) {
229                 rc = SMBOWFencrypt(nt_pwd.hash, chal,
230                               local_nt_response);
231                 if (rc != 0) {
232                         return false;
233                 }
234         }
235
236         {
237                 bool ret;
238                 NTSTATUS nt_status;
239                 DATA_BLOB local_lm_blob = data_blob_null;
240                 DATA_BLOB local_nt_blob = data_blob_null;
241
242                 if (lm_interactive_pwd) {
243                         local_lm_blob = data_blob(local_lm_response,
244                                                   sizeof(local_lm_response));
245                 }
246
247                 if (nt_interactive_pwd) {
248                         local_nt_blob = data_blob(local_nt_response,
249                                                   sizeof(local_nt_response));
250                 }
251
252                 nt_status = make_user_info_map(
253                         mem_ctx,
254                         user_info,
255                         smb_name, client_domain, workstation_name,
256                         remote_address,
257                         local_address,
258                         "SamLogon",
259                         lm_interactive_pwd ? &local_lm_blob : NULL,
260                         nt_interactive_pwd ? &local_nt_blob : NULL,
261                         lm_interactive_pwd ? &lm_pwd : NULL,
262                         nt_interactive_pwd ? &nt_pwd : NULL,
263                         NULL, AUTH_PASSWORD_HASH);
264
265                 if (NT_STATUS_IS_OK(nt_status)) {
266                         (*user_info)->logon_parameters = logon_parameters;
267                         (*user_info)->flags |= USER_INFO_INTERACTIVE_LOGON;
268                 }
269
270                 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
271                 data_blob_free(&local_lm_blob);
272                 data_blob_free(&local_nt_blob);
273                 return ret;
274         }
275 }
276
277
278 /****************************************************************************
279  Create an auth_usersupplied_data structure
280 ****************************************************************************/
281
282 bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
283                               struct auth_usersupplied_info **user_info,
284                               const char *smb_name,
285                               const char *client_domain,
286                               const struct tsocket_address *remote_address,
287                               const struct tsocket_address *local_address,
288                               const char *service_description,
289                               const uint8_t chal[8],
290                               DATA_BLOB plaintext_password)
291 {
292
293         DATA_BLOB local_lm_blob;
294         DATA_BLOB local_nt_blob;
295         NTSTATUS ret;
296         char *plaintext_password_string;
297         /*
298          * Not encrypted - do so.
299          */
300
301         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
302                  "format.\n"));
303         if (plaintext_password.data && plaintext_password.length) {
304                 unsigned char local_lm_response[24];
305
306 #ifdef DEBUG_PASSWORD
307                 DEBUG(10,("Unencrypted password (len %d):\n",
308                           (int)plaintext_password.length));
309                 dump_data(100, plaintext_password.data,
310                           plaintext_password.length);
311 #endif
312
313                 SMBencrypt( (const char *)plaintext_password.data,
314                             (const uchar*)chal, local_lm_response);
315                 local_lm_blob = data_blob(local_lm_response, 24);
316
317                 /* We can't do an NT hash here, as the password needs to be
318                    case insensitive */
319                 local_nt_blob = data_blob_null;
320         } else {
321                 local_lm_blob = data_blob_null;
322                 local_nt_blob = data_blob_null;
323         }
324
325         plaintext_password_string = talloc_strndup(talloc_tos(),
326                                                    (const char *)plaintext_password.data,
327                                                    plaintext_password.length);
328         if (!plaintext_password_string) {
329                 return false;
330         }
331
332         ret = make_user_info(mem_ctx,
333                 user_info, smb_name, smb_name, client_domain, client_domain,
334                 get_remote_machine_name(),
335                 remote_address,
336                 local_address,
337                 service_description,
338                 local_lm_blob.data ? &local_lm_blob : NULL,
339                 local_nt_blob.data ? &local_nt_blob : NULL,
340                 NULL, NULL,
341                 plaintext_password_string,
342                 AUTH_PASSWORD_PLAIN);
343
344         if (plaintext_password_string) {
345                 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
346                 talloc_free(plaintext_password_string);
347         }
348
349         data_blob_free(&local_lm_blob);
350         return NT_STATUS_IS_OK(ret) ? true : false;
351 }
352
353 /****************************************************************************
354  Create an auth_usersupplied_data structure
355 ****************************************************************************/
356
357 NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
358                                       struct auth_usersupplied_info **user_info,
359                                       const char *smb_name,
360                                       const char *client_domain,
361                                       const struct tsocket_address *remote_address,
362                                       const struct tsocket_address *local_address,
363                                       const char *service_description,
364                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
365 {
366         bool allow_raw = lp_raw_ntlmv2_auth();
367
368         if (!allow_raw && nt_resp.length >= 48) {
369                 /*
370                  * NTLMv2_RESPONSE has at least 48 bytes
371                  * and should only be supported via NTLMSSP.
372                  */
373                 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
374                          "user [%s\\%s] from[%s]\n",
375                          client_domain, smb_name,
376                          tsocket_address_string(remote_address, mem_ctx)));
377                 return NT_STATUS_INVALID_PARAMETER;
378         }
379
380         return make_user_info(mem_ctx,
381                               user_info, smb_name, smb_name,
382                               client_domain, client_domain,
383                               get_remote_machine_name(),
384                               remote_address,
385                               local_address,
386                               service_description,
387                               lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
388                               nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
389                               NULL, NULL, NULL,
390                               AUTH_PASSWORD_RESPONSE);
391 }
392
393 /****************************************************************************
394  Create a guest user_info blob, for anonymous authentication.
395 ****************************************************************************/
396
397 bool make_user_info_guest(TALLOC_CTX *mem_ctx,
398                           const struct tsocket_address *remote_address,
399                           const struct tsocket_address *local_address,
400                           const char *service_description,
401                           struct auth_usersupplied_info **user_info)
402 {
403         NTSTATUS nt_status;
404
405         nt_status = make_user_info(mem_ctx,
406                                    user_info,
407                                    "","",
408                                    "","",
409                                    "",
410                                    remote_address,
411                                    local_address,
412                                    service_description,
413                                    NULL, NULL,
414                                    NULL, NULL,
415                                    NULL,
416                                    AUTH_PASSWORD_RESPONSE);
417
418         return NT_STATUS_IS_OK(nt_status) ? true : false;
419 }
420
421 static NTSTATUS log_nt_token(struct security_token *token)
422 {
423         TALLOC_CTX *frame = talloc_stackframe();
424         const struct loadparm_substitution *lp_sub =
425                 loadparm_s3_global_substitution();
426         char *command;
427         char *group_sidstr;
428         struct dom_sid_buf buf;
429         size_t i;
430
431         if ((lp_log_nt_token_command(frame, lp_sub) == NULL) ||
432             (strlen(lp_log_nt_token_command(frame, lp_sub)) == 0)) {
433                 TALLOC_FREE(frame);
434                 return NT_STATUS_OK;
435         }
436
437         group_sidstr = talloc_strdup(frame, "");
438         for (i=1; i<token->num_sids; i++) {
439                 group_sidstr = talloc_asprintf(
440                         frame, "%s %s", group_sidstr,
441                         dom_sid_str_buf(&token->sids[i], &buf));
442         }
443
444         command = talloc_string_sub(
445                 frame, lp_log_nt_token_command(frame, lp_sub),
446                 "%s", dom_sid_str_buf(&token->sids[0], &buf));
447         command = talloc_string_sub(frame, command, "%t", group_sidstr);
448
449         if (command == NULL) {
450                 TALLOC_FREE(frame);
451                 return NT_STATUS_NO_MEMORY;
452         }
453
454         DEBUG(8, ("running command: [%s]\n", command));
455         if (smbrun(command, NULL, NULL) != 0) {
456                 DEBUG(0, ("Could not log NT token\n"));
457                 TALLOC_FREE(frame);
458                 return NT_STATUS_ACCESS_DENIED;
459         }
460
461         TALLOC_FREE(frame);
462         return NT_STATUS_OK;
463 }
464
465 /*
466  * Create the token to use from server_info->info3 and
467  * server_info->sids (the info3/sam groups). Find the unix gids.
468  */
469
470 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
471                             const struct auth_serversupplied_info *server_info,
472                             DATA_BLOB *session_key,
473                             const char *smb_username, /* for ->sanitized_username, for %U subs */
474                             struct auth_session_info **session_info_out)
475 {
476         struct security_token *t;
477         NTSTATUS status;
478         size_t i;
479         struct dom_sid tmp_sid;
480         struct auth_session_info *session_info = NULL;
481         struct unixid *ids;
482         bool is_allowed = false;
483
484         /* Ensure we can't possible take a code path leading to a
485          * null deref. */
486         if (!server_info) {
487                 return NT_STATUS_LOGON_FAILURE;
488         }
489
490         if (is_allowed_domain(server_info->info3->base.logon_domain.string)) {
491                 is_allowed = true;
492         }
493
494         /* Check if we have extra info about the user. */
495         if (dom_sid_in_domain(&global_sid_Unix_Users,
496                               &server_info->extra.user_sid) ||
497             dom_sid_in_domain(&global_sid_Unix_Groups,
498                               &server_info->extra.pgid_sid))
499         {
500                 is_allowed = true;
501         }
502
503         if (!is_allowed) {
504                 DBG_NOTICE("Authentication failed for user [%s] "
505                            "from firewalled domain [%s]\n",
506                            server_info->info3->base.account_name.string,
507                            server_info->info3->base.logon_domain.string);
508                 return NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
509         }
510
511         if (server_info->cached_session_info != NULL) {
512                 session_info = copy_session_info(mem_ctx,
513                                 server_info->cached_session_info);
514                 if (session_info == NULL) {
515                         goto nomem;
516                 }
517
518                 /* This is a potentially untrusted username for use in %U */
519                 session_info->unix_info->sanitized_username =
520                         talloc_alpha_strcpy(session_info->unix_info,
521                                             smb_username,
522                                             SAFE_NETBIOS_CHARS "$");
523                 if (session_info->unix_info->sanitized_username == NULL) {
524                         goto nomem;
525                 }
526
527                 session_info->unique_session_token = GUID_random();
528
529                 *session_info_out = session_info;
530                 return NT_STATUS_OK;
531         }
532
533         session_info = talloc_zero(mem_ctx, struct auth_session_info);
534         if (!session_info) {
535                 goto nomem;
536         }
537
538         session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
539         if (!session_info->unix_token) {
540                 goto nomem;
541         }
542
543         session_info->unix_token->uid = server_info->utok.uid;
544         session_info->unix_token->gid = server_info->utok.gid;
545
546         session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
547         if (!session_info->unix_info) {
548                 goto nomem;
549         }
550
551         session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
552         if (!session_info->unix_info->unix_name) {
553                 goto nomem;
554         }
555
556         /* This is a potentially untrusted username for use in %U */
557         session_info->unix_info->sanitized_username =
558                 talloc_alpha_strcpy(session_info->unix_info,
559                                     smb_username,
560                                     SAFE_NETBIOS_CHARS "$");
561         if (session_info->unix_info->sanitized_username == NULL) {
562                 goto nomem;
563         }
564
565         if (session_key) {
566                 data_blob_free(&session_info->session_key);
567                 session_info->session_key = data_blob_talloc(session_info,
568                                                                   session_key->data,
569                                                                   session_key->length);
570                 if (!session_info->session_key.data && session_key->length) {
571                         goto nomem;
572                 }
573         } else {
574                 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
575                                                               server_info->session_key.length);
576         }
577
578         /* We need to populate session_info->info with the information found in server_info->info3 */
579         status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
580                                             server_info->guest == false,
581                                             &session_info->info);
582         if (!NT_STATUS_IS_OK(status)) {
583                 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
584                 goto fail;
585         }
586
587         /*
588          * If the user name was mapped to some local unix user,
589          * we can not make much use of the SIDs the
590          * domain controller provided us with.
591          */
592         if (server_info->nss_token) {
593                 char *found_username = NULL;
594                 status = create_token_from_username(session_info,
595                                                     server_info->unix_name,
596                                                     server_info->guest,
597                                                     &session_info->unix_token->uid,
598                                                     &session_info->unix_token->gid,
599                                                     &found_username,
600                                                     &session_info->security_token);
601                 if (NT_STATUS_IS_OK(status)) {
602                         session_info->unix_info->unix_name = found_username;
603                 }
604         } else {
605                 status = create_local_nt_token_from_info3(session_info,
606                                                           server_info->guest,
607                                                           server_info->info3,
608                                                           &server_info->extra,
609                                                           &session_info->security_token);
610         }
611
612         if (!NT_STATUS_IS_OK(status)) {
613                 goto fail;
614         }
615
616         /* Convert the SIDs to gids. */
617
618         session_info->unix_token->ngroups = 0;
619         session_info->unix_token->groups = NULL;
620
621         t = session_info->security_token;
622
623         ids = talloc_array(talloc_tos(), struct unixid,
624                            t->num_sids);
625         if (ids == NULL) {
626                 goto nomem;
627         }
628
629         if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
630                 goto nomem;
631         }
632
633         for (i=0; i<t->num_sids; i++) {
634
635                 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
636                         continue;
637                 }
638
639                 if (ids[i].type != ID_TYPE_GID &&
640                     ids[i].type != ID_TYPE_BOTH) {
641                         struct dom_sid_buf buf;
642                         DEBUG(10, ("Could not convert SID %s to gid, "
643                                    "ignoring it\n",
644                                    dom_sid_str_buf(&t->sids[i], &buf)));
645                         continue;
646                 }
647                 if (!add_gid_to_array_unique(session_info->unix_token,
648                                              ids[i].id,
649                                              &session_info->unix_token->groups,
650                                              &session_info->unix_token->ngroups)) {
651                         goto nomem;
652                 }
653         }
654
655         /*
656          * Add the "Unix Group" SID for each gid to catch mapped groups
657          * and their Unix equivalent.  This is to solve the backwards
658          * compatibility problem of 'valid users = +ntadmin' where
659          * ntadmin has been paired with "Domain Admins" in the group
660          * mapping table.  Otherwise smb.conf would need to be changed
661          * to 'valid user = "Domain Admins"'.  --jerry
662          *
663          * For consistency we also add the "Unix User" SID,
664          * so that the complete unix token is represented within
665          * the nt token.
666          */
667
668         uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
669         status = add_sid_to_array_unique(
670                 session_info->security_token,
671                 &tmp_sid,
672                 &session_info->security_token->sids,
673                 &session_info->security_token->num_sids);
674         if (!NT_STATUS_IS_OK(status)) {
675                 goto fail;
676         }
677
678         gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
679         status = add_sid_to_array_unique(
680                 session_info->security_token,
681                 &tmp_sid,
682                 &session_info->security_token->sids,
683                 &session_info->security_token->num_sids);
684         if (!NT_STATUS_IS_OK(status)) {
685                 goto fail;
686         }
687
688         for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
689                 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
690                 status = add_sid_to_array_unique(
691                         session_info->security_token,
692                         &tmp_sid,
693                         &session_info->security_token->sids,
694                         &session_info->security_token->num_sids);
695                 if (!NT_STATUS_IS_OK(status)) {
696                         goto fail;
697                 }
698         }
699
700         security_token_debug(DBGC_AUTH, 10, session_info->security_token);
701         debug_unix_user_token(DBGC_AUTH, 10,
702                               session_info->unix_token->uid,
703                               session_info->unix_token->gid,
704                               session_info->unix_token->ngroups,
705                               session_info->unix_token->groups);
706
707         status = log_nt_token(session_info->security_token);
708         if (!NT_STATUS_IS_OK(status)) {
709                 goto fail;
710         }
711
712         session_info->unique_session_token = GUID_random();
713
714         *session_info_out = session_info;
715         return NT_STATUS_OK;
716 nomem:
717         status = NT_STATUS_NO_MEMORY;
718 fail:
719         TALLOC_FREE(session_info);
720         return status;
721 }
722
723 NTSTATUS auth3_user_info_dc_add_hints(struct auth_user_info_dc *user_info_dc,
724                                       uid_t uid,
725                                       gid_t gid,
726                                       uint32_t flags)
727 {
728         uint32_t orig_num_sids = user_info_dc->num_sids;
729         struct dom_sid tmp_sid = { 0, };
730         NTSTATUS status;
731
732         /*
733          * We add S-5-88-1-X in order to pass the uid
734          * for the unix token.
735          */
736         sid_compose(&tmp_sid,
737                     &global_sid_Unix_NFS_Users,
738                     (uint32_t)uid);
739         status = add_sid_to_array_attrs_unique(user_info_dc->sids,
740                                                &tmp_sid,
741                                                SE_GROUP_DEFAULT_FLAGS,
742                                                &user_info_dc->sids,
743                                                &user_info_dc->num_sids);
744         if (!NT_STATUS_IS_OK(status)) {
745                 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
746                           nt_errstr(status)));
747                 goto fail;
748         }
749
750         /*
751          * We add S-5-88-2-X in order to pass the gid
752          * for the unix token.
753          */
754         sid_compose(&tmp_sid,
755                     &global_sid_Unix_NFS_Groups,
756                     (uint32_t)gid);
757         status = add_sid_to_array_attrs_unique(user_info_dc->sids,
758                                                &tmp_sid,
759                                                SE_GROUP_DEFAULT_FLAGS,
760                                                &user_info_dc->sids,
761                                                &user_info_dc->num_sids);
762         if (!NT_STATUS_IS_OK(status)) {
763                 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
764                           nt_errstr(status)));
765                 goto fail;
766         }
767
768         /*
769          * We add S-5-88-3-X in order to pass some flags
770          * (AUTH3_UNIX_HINT_*) to auth3_create_session_info().
771          */
772         sid_compose(&tmp_sid,
773                     &global_sid_Unix_NFS_Mode,
774                     flags);
775         status = add_sid_to_array_attrs_unique(user_info_dc->sids,
776                                                &tmp_sid,
777                                                SE_GROUP_DEFAULT_FLAGS,
778                                                &user_info_dc->sids,
779                                                &user_info_dc->num_sids);
780         if (!NT_STATUS_IS_OK(status)) {
781                 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
782                           nt_errstr(status)));
783                 goto fail;
784         }
785
786         return NT_STATUS_OK;
787
788 fail:
789         user_info_dc->num_sids = orig_num_sids;
790         return status;
791 }
792
793 static NTSTATUS auth3_session_info_create(
794         TALLOC_CTX *mem_ctx,
795         const struct auth_user_info_dc *user_info_dc,
796         const char *original_user_name,
797         uint32_t session_info_flags,
798         struct auth_session_info **session_info_out)
799 {
800         TALLOC_CTX *frame = talloc_stackframe();
801         struct auth_session_info *session_info = NULL;
802         uid_t hint_uid = -1;
803         bool found_hint_uid = false;
804         uid_t hint_gid = -1;
805         bool found_hint_gid = false;
806         uint32_t hint_flags = 0;
807         bool found_hint_flags = false;
808         bool need_getpwuid = false;
809         struct unixid *ids = NULL;
810         uint32_t num_gids = 0;
811         gid_t *gids = NULL;
812         struct dom_sid tmp_sid = { 0, };
813         NTSTATUS status;
814         size_t i;
815         bool ok;
816
817         *session_info_out = NULL;
818
819         if (user_info_dc->num_sids == 0) {
820                 TALLOC_FREE(frame);
821                 return NT_STATUS_INVALID_TOKEN;
822         }
823
824         if (user_info_dc->info == NULL) {
825                 TALLOC_FREE(frame);
826                 return NT_STATUS_INVALID_TOKEN;
827         }
828
829         if (user_info_dc->info->account_name == NULL) {
830                 TALLOC_FREE(frame);
831                 return NT_STATUS_INVALID_TOKEN;
832         }
833
834         session_info = talloc_zero(mem_ctx, struct auth_session_info);
835         if (session_info == NULL) {
836                 TALLOC_FREE(frame);
837                 return NT_STATUS_NO_MEMORY;
838         }
839         /* keep this under frame for easier cleanup */
840         talloc_reparent(mem_ctx, frame, session_info);
841
842         session_info->info = auth_user_info_copy(session_info,
843                                                  user_info_dc->info);
844         if (session_info->info == NULL) {
845                 TALLOC_FREE(frame);
846                 return NT_STATUS_NO_MEMORY;
847         }
848
849         session_info->security_token = talloc_zero(session_info,
850                                                    struct security_token);
851         if (session_info->security_token == NULL) {
852                 TALLOC_FREE(frame);
853                 return NT_STATUS_NO_MEMORY;
854         }
855
856         /*
857          * Avoid a lot of reallocations and allocate what we'll
858          * use in most cases.
859          */
860         session_info->security_token->sids = talloc_zero_array(
861                                                 session_info->security_token,
862                                                 struct dom_sid,
863                                                 user_info_dc->num_sids);
864         if (session_info->security_token->sids == NULL) {
865                 TALLOC_FREE(frame);
866                 return NT_STATUS_NO_MEMORY;
867         }
868
869         for (i = PRIMARY_USER_SID_INDEX; i < user_info_dc->num_sids; i++) {
870                 struct security_token *nt_token = session_info->security_token;
871                 int cmp;
872
873                 /*
874                  * S-1-5-88-X-Y sids are only used to give hints
875                  * to the unix token construction.
876                  *
877                  * S-1-5-88-1-Y gives the uid=Y
878                  * S-1-5-88-2-Y gives the gid=Y
879                  * S-1-5-88-3-Y gives flags=Y: AUTH3_UNIX_HINT_*
880                  */
881                 cmp = dom_sid_compare_domain(&global_sid_Unix_NFS,
882                                              &user_info_dc->sids[i].sid);
883                 if (cmp == 0) {
884                         bool match;
885                         uint32_t hint = 0;
886
887                         match = sid_peek_rid(&user_info_dc->sids[i].sid, &hint);
888                         if (!match) {
889                                 continue;
890                         }
891
892                         match = dom_sid_in_domain(&global_sid_Unix_NFS_Users,
893                                                   &user_info_dc->sids[i].sid);
894                         if (match) {
895                                 if (found_hint_uid) {
896                                         TALLOC_FREE(frame);
897                                         return NT_STATUS_INVALID_TOKEN;
898                                 }
899                                 found_hint_uid = true;
900                                 hint_uid = (uid_t)hint;
901                                 continue;
902                         }
903
904                         match = dom_sid_in_domain(&global_sid_Unix_NFS_Groups,
905                                                   &user_info_dc->sids[i].sid);
906                         if (match) {
907                                 if (found_hint_gid) {
908                                         TALLOC_FREE(frame);
909                                         return NT_STATUS_INVALID_TOKEN;
910                                 }
911                                 found_hint_gid = true;
912                                 hint_gid = (gid_t)hint;
913                                 continue;
914                         }
915
916                         match = dom_sid_in_domain(&global_sid_Unix_NFS_Mode,
917                                                   &user_info_dc->sids[i].sid);
918                         if (match) {
919                                 if (found_hint_flags) {
920                                         TALLOC_FREE(frame);
921                                         return NT_STATUS_INVALID_TOKEN;
922                                 }
923                                 found_hint_flags = true;
924                                 hint_flags = hint;
925                                 continue;
926                         }
927
928                         continue;
929                 }
930
931                 status = add_sid_to_array_unique(nt_token->sids,
932                                                  &user_info_dc->sids[i].sid,
933                                                  &nt_token->sids,
934                                                  &nt_token->num_sids);
935                 if (!NT_STATUS_IS_OK(status)) {
936                         TALLOC_FREE(frame);
937                         return status;
938                 }
939         }
940
941         /*
942          * We need at least one usable SID
943          */
944         if (session_info->security_token->num_sids == 0) {
945                 TALLOC_FREE(frame);
946                 return NT_STATUS_INVALID_TOKEN;
947         }
948
949         /*
950          * We need all tree hints: uid, gid, flags
951          * or none of them.
952          */
953         if (found_hint_uid || found_hint_gid || found_hint_flags) {
954                 if (!found_hint_uid) {
955                         TALLOC_FREE(frame);
956                         return NT_STATUS_INVALID_TOKEN;
957                 }
958
959                 if (!found_hint_gid) {
960                         TALLOC_FREE(frame);
961                         return NT_STATUS_INVALID_TOKEN;
962                 }
963
964                 if (!found_hint_flags) {
965                         TALLOC_FREE(frame);
966                         return NT_STATUS_INVALID_TOKEN;
967                 }
968         }
969
970         if (!(user_info_dc->info->user_flags & NETLOGON_GUEST)) {
971                 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
972         }
973
974         status = finalize_local_nt_token(session_info->security_token,
975                                          session_info_flags);
976         if (!NT_STATUS_IS_OK(status)) {
977                 TALLOC_FREE(frame);
978                 return status;
979         }
980
981         /*
982          * unless set otherwise, the session key is the user session
983          * key from the auth subsystem
984          */
985         if (user_info_dc->user_session_key.length != 0) {
986                 session_info->session_key = data_blob_dup_talloc(session_info,
987                                                 user_info_dc->user_session_key);
988                 if (session_info->session_key.data == NULL) {
989                         TALLOC_FREE(frame);
990                         return NT_STATUS_NO_MEMORY;
991                 }
992         }
993
994         if (!(session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)) {
995                 goto done;
996         }
997
998         session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
999         if (session_info->unix_token == NULL) {
1000                 TALLOC_FREE(frame);
1001                 return NT_STATUS_NO_MEMORY;
1002         }
1003         session_info->unix_token->uid = -1;
1004         session_info->unix_token->gid = -1;
1005
1006         session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
1007         if (session_info->unix_info == NULL) {
1008                 TALLOC_FREE(frame);
1009                 return NT_STATUS_NO_MEMORY;
1010         }
1011
1012         /* Convert the SIDs to uid/gids. */
1013
1014         ids = talloc_zero_array(frame, struct unixid,
1015                                 session_info->security_token->num_sids);
1016         if (ids == NULL) {
1017                 TALLOC_FREE(frame);
1018                 return NT_STATUS_NO_MEMORY;
1019         }
1020
1021         if (!(hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS)) {
1022                 ok = sids_to_unixids(session_info->security_token->sids,
1023                                      session_info->security_token->num_sids,
1024                                      ids);
1025                 if (!ok) {
1026                         TALLOC_FREE(frame);
1027                         return NT_STATUS_NO_MEMORY;
1028                 }
1029         }
1030
1031         if (found_hint_uid) {
1032                 session_info->unix_token->uid = hint_uid;
1033         } else if (ids[0].type == ID_TYPE_UID) {
1034                 /*
1035                  * The primary SID resolves to a UID only.
1036                  */
1037                 session_info->unix_token->uid = ids[0].id;
1038         } else if (ids[0].type == ID_TYPE_BOTH) {
1039                 /*
1040                  * The primary SID resolves to a UID and GID,
1041                  * use it as uid and add it as first element
1042                  * to the groups array.
1043                  */
1044                 session_info->unix_token->uid = ids[0].id;
1045
1046                 ok = add_gid_to_array_unique(session_info->unix_token,
1047                                              session_info->unix_token->uid,
1048                                              &session_info->unix_token->groups,
1049                                              &session_info->unix_token->ngroups);
1050                 if (!ok) {
1051                         TALLOC_FREE(frame);
1052                         return NT_STATUS_NO_MEMORY;
1053                 }
1054         } else {
1055                 /*
1056                  * It we can't get a uid, we can't imporsonate
1057                  * the user.
1058                  */
1059                 TALLOC_FREE(frame);
1060                 return NT_STATUS_INVALID_TOKEN;
1061         }
1062
1063         if (found_hint_gid) {
1064                 session_info->unix_token->gid = hint_gid;
1065         } else {
1066                 need_getpwuid = true;
1067         }
1068
1069         if (hint_flags & AUTH3_UNIX_HINT_QUALIFIED_NAME) {
1070                 session_info->unix_info->unix_name =
1071                         talloc_asprintf(session_info->unix_info,
1072                                         "%s%c%s",
1073                                         session_info->info->domain_name,
1074                                         *lp_winbind_separator(),
1075                                         session_info->info->account_name);
1076                 if (session_info->unix_info->unix_name == NULL) {
1077                         TALLOC_FREE(frame);
1078                         return NT_STATUS_NO_MEMORY;
1079                 }
1080         } else if (hint_flags & AUTH3_UNIX_HINT_ISLOLATED_NAME) {
1081                 session_info->unix_info->unix_name =
1082                         talloc_strdup(session_info->unix_info,
1083                                       session_info->info->account_name);
1084                 if (session_info->unix_info->unix_name == NULL) {
1085                         TALLOC_FREE(frame);
1086                         return NT_STATUS_NO_MEMORY;
1087                 }
1088         } else {
1089                 need_getpwuid = true;
1090         }
1091
1092         if (need_getpwuid) {
1093                 struct passwd *pwd = NULL;
1094
1095                 /*
1096                  * Ask the system for the primary gid
1097                  * and the real unix name.
1098                  */
1099                 pwd = getpwuid_alloc(frame, session_info->unix_token->uid);
1100                 if (pwd == NULL) {
1101                         TALLOC_FREE(frame);
1102                         return NT_STATUS_INVALID_TOKEN;
1103                 }
1104                 if (!found_hint_gid) {
1105                         session_info->unix_token->gid = pwd->pw_gid;
1106                 }
1107
1108                 session_info->unix_info->unix_name =
1109                         talloc_strdup(session_info->unix_info, pwd->pw_name);
1110                 if (session_info->unix_info->unix_name == NULL) {
1111                         TALLOC_FREE(frame);
1112                         return NT_STATUS_NO_MEMORY;
1113                 }
1114
1115                 TALLOC_FREE(pwd);
1116         }
1117
1118         ok = add_gid_to_array_unique(session_info->unix_token,
1119                                      session_info->unix_token->gid,
1120                                      &session_info->unix_token->groups,
1121                                      &session_info->unix_token->ngroups);
1122         if (!ok) {
1123                 TALLOC_FREE(frame);
1124                 return NT_STATUS_NO_MEMORY;
1125         }
1126
1127         /* This is a potentially untrusted username for use in %U */
1128         session_info->unix_info->sanitized_username =
1129                 talloc_alpha_strcpy(session_info->unix_info,
1130                                     original_user_name,
1131                                     SAFE_NETBIOS_CHARS "$");
1132         if (session_info->unix_info->sanitized_username == NULL) {
1133                 TALLOC_FREE(frame);
1134                 return NT_STATUS_NO_MEMORY;
1135         }
1136
1137         for (i=0; i < session_info->security_token->num_sids; i++) {
1138
1139                 if (ids[i].type != ID_TYPE_GID &&
1140                     ids[i].type != ID_TYPE_BOTH) {
1141                         struct security_token *nt_token =
1142                                 session_info->security_token;
1143                         struct dom_sid_buf buf;
1144
1145                         DEBUG(10, ("Could not convert SID %s to gid, "
1146                                    "ignoring it\n",
1147                                    dom_sid_str_buf(&nt_token->sids[i], &buf)));
1148                         continue;
1149                 }
1150
1151                 ok = add_gid_to_array_unique(session_info->unix_token,
1152                                              ids[i].id,
1153                                              &session_info->unix_token->groups,
1154                                              &session_info->unix_token->ngroups);
1155                 if (!ok) {
1156                         TALLOC_FREE(frame);
1157                         return NT_STATUS_NO_MEMORY;
1158                 }
1159         }
1160         TALLOC_FREE(ids);
1161
1162         /*
1163          * Now we must get any groups this user has been
1164          * added to in /etc/group and merge them in.
1165          * This has to be done in every code path
1166          * that creates an NT token, as remote users
1167          * may have been added to the local /etc/group
1168          * database. Tokens created merely from the
1169          * info3 structs (via the DC or via the krb5 PAC)
1170          * won't have these local groups. Note the
1171          * groups added here will only be UNIX groups
1172          * (S-1-22-2-XXXX groups) as getgroups_unix_user()
1173          * turns off winbindd before calling getgroups().
1174          *
1175          * NB. This is duplicating work already
1176          * done in the 'unix_user:' case of
1177          * create_token_from_sid() but won't
1178          * do anything other than be inefficient
1179          * in that case.
1180          */
1181         if (!(hint_flags & AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS)) {
1182                 ok = getgroups_unix_user(frame,
1183                                          session_info->unix_info->unix_name,
1184                                          session_info->unix_token->gid,
1185                                          &gids, &num_gids);
1186                 if (!ok) {
1187                         TALLOC_FREE(frame);
1188                         return NT_STATUS_INVALID_TOKEN;
1189                 }
1190         }
1191
1192         for (i=0; i < num_gids; i++) {
1193
1194                 ok = add_gid_to_array_unique(session_info->unix_token,
1195                                              gids[i],
1196                                              &session_info->unix_token->groups,
1197                                              &session_info->unix_token->ngroups);
1198                 if (!ok) {
1199                         TALLOC_FREE(frame);
1200                         return NT_STATUS_NO_MEMORY;
1201                 }
1202         }
1203         TALLOC_FREE(gids);
1204
1205         if (hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS) {
1206                 /*
1207                  * We should not translate the unix token uid/gids
1208                  * to S-1-22-X-Y SIDs.
1209                  */
1210                 goto done;
1211         }
1212
1213         /*
1214          * Add the "Unix Group" SID for each gid to catch mapped groups
1215          * and their Unix equivalent.  This is to solve the backwards
1216          * compatibility problem of 'valid users = +ntadmin' where
1217          * ntadmin has been paired with "Domain Admins" in the group
1218          * mapping table.  Otherwise smb.conf would need to be changed
1219          * to 'valid user = "Domain Admins"'.  --jerry
1220          *
1221          * For consistency we also add the "Unix User" SID,
1222          * so that the complete unix token is represented within
1223          * the nt token.
1224          */
1225
1226         uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
1227         status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1228                                          &session_info->security_token->sids,
1229                                          &session_info->security_token->num_sids);
1230         if (!NT_STATUS_IS_OK(status)) {
1231                 TALLOC_FREE(frame);
1232                 return status;
1233         }
1234
1235         gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
1236         status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1237                                          &session_info->security_token->sids,
1238                                          &session_info->security_token->num_sids);
1239         if (!NT_STATUS_IS_OK(status)) {
1240                 TALLOC_FREE(frame);
1241                 return status;
1242         }
1243
1244         for (i=0; i < session_info->unix_token->ngroups; i++ ) {
1245                 struct security_token *nt_token = session_info->security_token;
1246
1247                 gid_to_unix_groups_sid(session_info->unix_token->groups[i],
1248                                        &tmp_sid);
1249                 status = add_sid_to_array_unique(nt_token->sids,
1250                                                  &tmp_sid,
1251                                                  &nt_token->sids,
1252                                                  &nt_token->num_sids);
1253                 if (!NT_STATUS_IS_OK(status)) {
1254                         TALLOC_FREE(frame);
1255                         return status;
1256                 }
1257         }
1258
1259 done:
1260         security_token_debug(DBGC_AUTH, 10, session_info->security_token);
1261         if (session_info->unix_token != NULL) {
1262                 debug_unix_user_token(DBGC_AUTH, 10,
1263                                       session_info->unix_token->uid,
1264                                       session_info->unix_token->gid,
1265                                       session_info->unix_token->ngroups,
1266                                       session_info->unix_token->groups);
1267         }
1268
1269         status = log_nt_token(session_info->security_token);
1270         if (!NT_STATUS_IS_OK(status)) {
1271                 TALLOC_FREE(frame);
1272                 return status;
1273         }
1274
1275         session_info->unique_session_token = GUID_random();
1276
1277         *session_info_out = talloc_move(mem_ctx, &session_info);
1278         TALLOC_FREE(frame);
1279         return NT_STATUS_OK;
1280 }
1281
1282 /***************************************************************************
1283  Make (and fill) a server_info struct from a 'struct passwd' by conversion
1284  to a struct samu
1285 ***************************************************************************/
1286
1287 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
1288                              const char *unix_username,
1289                              const struct passwd *pwd,
1290                              struct auth_serversupplied_info **server_info)
1291 {
1292         NTSTATUS status;
1293         TALLOC_CTX *tmp_ctx = NULL;
1294         struct auth_serversupplied_info *result;
1295
1296         tmp_ctx = talloc_stackframe();
1297         if (tmp_ctx == NULL) {
1298                 return NT_STATUS_NO_MEMORY;
1299         }
1300
1301         result = make_server_info(tmp_ctx);
1302         if (result == NULL) {
1303                 status = NT_STATUS_NO_MEMORY;
1304                 goto done;
1305         }
1306
1307         status = passwd_to_SamInfo3(result,
1308                                     unix_username,
1309                                     pwd,
1310                                     &result->info3,
1311                                     &result->extra);
1312         if (!NT_STATUS_IS_OK(status)) {
1313                 goto done;
1314         }
1315
1316         result->unix_name = talloc_strdup(result, unix_username);
1317         if (result->unix_name == NULL) {
1318                 status = NT_STATUS_NO_MEMORY;
1319                 goto done;
1320         }
1321
1322         result->utok.uid = pwd->pw_uid;
1323         result->utok.gid = pwd->pw_gid;
1324
1325         *server_info = talloc_move(mem_ctx, &result);
1326         status = NT_STATUS_OK;
1327 done:
1328         talloc_free(tmp_ctx);
1329
1330         return status;
1331 }
1332
1333 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
1334                                 struct netr_SamInfo3 *info3)
1335 {
1336         const char *guest_account = lp_guest_account();
1337         struct dom_sid domain_sid;
1338         struct passwd *pwd;
1339         const char *tmp;
1340
1341         pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
1342         if (pwd == NULL) {
1343                 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
1344                          "account [%s]!\n", guest_account));
1345                 return NT_STATUS_NO_SUCH_USER;
1346         }
1347
1348         /* Set account name */
1349         tmp = talloc_strdup(mem_ctx, pwd->pw_name);
1350         if (tmp == NULL) {
1351                 return NT_STATUS_NO_MEMORY;
1352         }
1353         init_lsa_String(&info3->base.account_name, tmp);
1354
1355         /* Set domain name */
1356         tmp = talloc_strdup(mem_ctx, get_global_sam_name());
1357         if (tmp == NULL) {
1358                 return NT_STATUS_NO_MEMORY;
1359         }
1360         init_lsa_StringLarge(&info3->base.logon_domain, tmp);
1361
1362         /* Domain sid */
1363         sid_copy(&domain_sid, get_global_sam_sid());
1364
1365         info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
1366         if (info3->base.domain_sid == NULL) {
1367                 return NT_STATUS_NO_MEMORY;
1368         }
1369
1370         /* Guest rid */
1371         info3->base.rid = DOMAIN_RID_GUEST;
1372
1373         /* Primary gid */
1374         info3->base.primary_gid = DOMAIN_RID_GUESTS;
1375
1376         /* Set as guest */
1377         info3->base.user_flags = NETLOGON_GUEST;
1378
1379         TALLOC_FREE(pwd);
1380         return NT_STATUS_OK;
1381 }
1382
1383 /***************************************************************************
1384  Make (and fill) a user_info struct for a guest login.
1385  This *must* succeed for smbd to start. If there is no mapping entry for
1386  the guest gid, then create one.
1387
1388  The resulting structure is a 'session_info' because
1389  create_local_token() has already been called on it.  This is quite
1390  nasty, as the auth subsystem isn't expect this, but the behavior is
1391  left as-is for now.
1392 ***************************************************************************/
1393
1394 static NTSTATUS make_new_session_info_guest(TALLOC_CTX *mem_ctx,
1395                 struct auth_session_info **_session_info,
1396                 struct auth_serversupplied_info **_server_info)
1397 {
1398         struct auth_session_info *session_info = NULL;
1399         struct auth_serversupplied_info *server_info = NULL;
1400         const char *guest_account = lp_guest_account();
1401         const char *domain = lp_netbios_name();
1402         struct netr_SamInfo3 info3;
1403         TALLOC_CTX *tmp_ctx;
1404         NTSTATUS status;
1405
1406         tmp_ctx = talloc_stackframe();
1407         if (tmp_ctx == NULL) {
1408                 return NT_STATUS_NO_MEMORY;
1409         }
1410
1411         ZERO_STRUCT(info3);
1412
1413         status = get_guest_info3(tmp_ctx, &info3);
1414         if (!NT_STATUS_IS_OK(status)) {
1415                 DEBUG(0, ("get_guest_info3 failed with %s\n",
1416                           nt_errstr(status)));
1417                 goto done;
1418         }
1419
1420         status = make_server_info_info3(tmp_ctx,
1421                                         guest_account,
1422                                         domain,
1423                                         &server_info,
1424                                         &info3);
1425         if (!NT_STATUS_IS_OK(status)) {
1426                 DEBUG(0, ("make_server_info_info3 failed with %s\n",
1427                           nt_errstr(status)));
1428                 goto done;
1429         }
1430
1431         server_info->guest = true;
1432
1433         /* This should not be done here (we should produce a server
1434          * info, and later construct a session info from it), but for
1435          * now this does not change the previous behavior */
1436         status = create_local_token(tmp_ctx, server_info, NULL,
1437                                     server_info->info3->base.account_name.string,
1438                                     &session_info);
1439         if (!NT_STATUS_IS_OK(status)) {
1440                 DEBUG(0, ("create_local_token failed: %s\n",
1441                           nt_errstr(status)));
1442                 goto done;
1443         }
1444
1445         /*
1446          * It's ugly, but for now it's
1447          * needed to force Builtin_Guests
1448          * here, because memberships of
1449          * Builtin_Guests might be incomplete.
1450          */
1451         status = add_sid_to_array_unique(session_info->security_token,
1452                                          &global_sid_Builtin_Guests,
1453                                          &session_info->security_token->sids,
1454                                          &session_info->security_token->num_sids);
1455         if (!NT_STATUS_IS_OK(status)) {
1456                 DBG_ERR("Failed to force Builtin_Guests to nt token\n");
1457                 goto done;
1458         }
1459
1460         /* annoying, but the Guest really does have a session key, and it is
1461            all zeros! */
1462         session_info->session_key = data_blob_talloc_zero(session_info, 16);
1463
1464         *_session_info = talloc_move(mem_ctx, &session_info);
1465         *_server_info = talloc_move(mem_ctx, &server_info);
1466
1467         status = NT_STATUS_OK;
1468 done:
1469         TALLOC_FREE(tmp_ctx);
1470         return status;
1471 }
1472
1473 /***************************************************************************
1474  Make (and fill) a auth_session_info struct for a system user login.
1475  This *must* succeed for smbd to start.
1476 ***************************************************************************/
1477
1478 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
1479                                             struct auth_session_info **session_info)
1480 {
1481         TALLOC_CTX *frame = talloc_stackframe();
1482         struct auth_user_info_dc *user_info_dc = NULL;
1483         uid_t uid = -1;
1484         gid_t gid = -1;
1485         uint32_t hint_flags = 0;
1486         uint32_t session_info_flags = 0;
1487         NTSTATUS status;
1488
1489         status = auth_system_user_info_dc(frame, lp_netbios_name(),
1490                                           &user_info_dc);
1491         if (!NT_STATUS_IS_OK(status)) {
1492                 DEBUG(0, ("auth_system_user_info_dc failed: %s\n",
1493                           nt_errstr(status)));
1494                 goto done;
1495         }
1496
1497         /*
1498          * Just get the initial uid/gid
1499          * and don't expand the unix groups.
1500          */
1501         uid = sec_initial_uid();
1502         gid = sec_initial_gid();
1503         hint_flags |= AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS;
1504
1505         /*
1506          * Also avoid sid mapping to gids,
1507          * as well as adding the unix_token uid/gids as
1508          * S-1-22-X-Y SIDs to the nt token.
1509          */
1510         hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS;
1511         hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS;
1512
1513         /*
1514          * The unix name will be "NT AUTHORITY+SYSTEM",
1515          * where '+' is the "winbind separator" character.
1516          */
1517         hint_flags |= AUTH3_UNIX_HINT_QUALIFIED_NAME;
1518         status = auth3_user_info_dc_add_hints(user_info_dc,
1519                                               uid,
1520                                               gid,
1521                                               hint_flags);
1522         if (!NT_STATUS_IS_OK(status)) {
1523                 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1524                           nt_errstr(status)));
1525                 goto done;
1526         }
1527
1528         session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1529         session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1530         status = auth3_session_info_create(mem_ctx, user_info_dc,
1531                                            user_info_dc->info->account_name,
1532                                            session_info_flags,
1533                                            session_info);
1534         if (!NT_STATUS_IS_OK(status)) {
1535                 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1536                           nt_errstr(status)));
1537                 goto done;
1538         }
1539
1540 done:
1541         TALLOC_FREE(frame);
1542         return status;
1543 }
1544
1545 static NTSTATUS make_new_session_info_anonymous(TALLOC_CTX *mem_ctx,
1546                                         struct auth_session_info **session_info)
1547 {
1548         TALLOC_CTX *frame = talloc_stackframe();
1549         const char *guest_account = lp_guest_account();
1550         struct auth_user_info_dc *user_info_dc = NULL;
1551         struct passwd *pwd = NULL;
1552         uint32_t hint_flags = 0;
1553         uint32_t session_info_flags = 0;
1554         NTSTATUS status;
1555
1556         /*
1557          * We use the guest account for the unix token
1558          * while we use a true anonymous nt token.
1559          *
1560          * It's very important to have a separate
1561          * nt token for anonymous.
1562          */
1563
1564         pwd = Get_Pwnam_alloc(frame, guest_account);
1565         if (pwd == NULL) {
1566                 DBG_ERR("Unable to locate guest account [%s]!\n",
1567                         guest_account);
1568                 status = NT_STATUS_NO_SUCH_USER;
1569                 goto done;
1570         }
1571
1572         status = auth_anonymous_user_info_dc(frame, lp_netbios_name(),
1573                                              &user_info_dc);
1574         if (!NT_STATUS_IS_OK(status)) {
1575                 DEBUG(0, ("auth_anonymous_user_info_dc failed: %s\n",
1576                           nt_errstr(status)));
1577                 goto done;
1578         }
1579
1580         /*
1581          * Note we don't pass AUTH3_UNIX_HINT_QUALIFIED_NAME
1582          * nor AUTH3_UNIX_HINT_ISOLATED_NAME here
1583          * as we want the unix name be found by getpwuid_alloc().
1584          */
1585
1586         status = auth3_user_info_dc_add_hints(user_info_dc,
1587                                               pwd->pw_uid,
1588                                               pwd->pw_gid,
1589                                               hint_flags);
1590         if (!NT_STATUS_IS_OK(status)) {
1591                 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1592                           nt_errstr(status)));
1593                 goto done;
1594         }
1595
1596         /*
1597          * In future we may want to remove
1598          * AUTH_SESSION_INFO_DEFAULT_GROUPS.
1599          *
1600          * Similar to Windows with EveryoneIncludesAnonymous
1601          * and RestrictAnonymous.
1602          *
1603          * We may introduce AUTH_SESSION_INFO_ANON_WORLD...
1604          *
1605          * But for this is required to keep the existing tests
1606          * working.
1607          */
1608         session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
1609         session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1610         session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1611         status = auth3_session_info_create(mem_ctx, user_info_dc,
1612                                            "",
1613                                            session_info_flags,
1614                                            session_info);
1615         if (!NT_STATUS_IS_OK(status)) {
1616                 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1617                           nt_errstr(status)));
1618                 goto done;
1619         }
1620
1621 done:
1622         TALLOC_FREE(frame);
1623         return status;
1624 }
1625
1626 /****************************************************************************
1627   Fake a auth_session_info just from a username (as a
1628   session_info structure, with create_local_token() already called on
1629   it.
1630 ****************************************************************************/
1631
1632 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
1633                                          const char *username,
1634                                          bool is_guest,
1635                                          struct auth_session_info **session_info)
1636 {
1637         struct passwd *pwd;
1638         NTSTATUS status;
1639         struct auth_serversupplied_info *result;
1640         TALLOC_CTX *tmp_ctx;
1641
1642         tmp_ctx = talloc_stackframe();
1643         if (tmp_ctx == NULL) {
1644                 return NT_STATUS_NO_MEMORY;
1645         }
1646
1647         pwd = Get_Pwnam_alloc(tmp_ctx, username);
1648         if (pwd == NULL) {
1649                 status = NT_STATUS_NO_SUCH_USER;
1650                 goto done;
1651         }
1652
1653         status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
1654         if (!NT_STATUS_IS_OK(status)) {
1655                 goto done;
1656         }
1657
1658         result->nss_token = true;
1659         result->guest = is_guest;
1660
1661         /* Now turn the server_info into a session_info with the full token etc */
1662         status = create_local_token(mem_ctx,
1663                                     result,
1664                                     NULL,
1665                                     pwd->pw_name,
1666                                     session_info);
1667
1668 done:
1669         talloc_free(tmp_ctx);
1670
1671         return status;
1672 }
1673
1674 /* This function MUST only used to create the cached server_info for
1675  * guest.
1676  *
1677  * This is a lossy conversion.  Variables known to be lost so far
1678  * include:
1679  *
1680  * - nss_token (not needed because the only read doesn't happen
1681  * for the GUEST user, as this routine populates ->security_token
1682  *
1683  * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1684  *
1685  * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1686  */
1687 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1688                                                                            const struct auth_session_info *src,
1689                                                                            struct auth_serversupplied_info *server_info)
1690 {
1691         struct auth_serversupplied_info *dst;
1692         NTSTATUS status;
1693
1694         dst = make_server_info(mem_ctx);
1695         if (dst == NULL) {
1696                 return NULL;
1697         }
1698
1699         /* This element must be provided to convert back to an auth_serversupplied_info */
1700         SMB_ASSERT(src->unix_info);
1701
1702         dst->guest = true;
1703
1704         /* This element must be provided to convert back to an
1705          * auth_serversupplied_info.  This needs to be from the
1706          * auth_session_info because the group values in particular
1707          * may change during create_local_token() processing */
1708         SMB_ASSERT(src->unix_token);
1709         dst->utok.uid = src->unix_token->uid;
1710         dst->utok.gid = src->unix_token->gid;
1711         dst->utok.ngroups = src->unix_token->ngroups;
1712         if (src->unix_token->ngroups != 0) {
1713                 dst->utok.groups = (gid_t *)talloc_memdup(
1714                         dst, src->unix_token->groups,
1715                         sizeof(gid_t)*dst->utok.ngroups);
1716         } else {
1717                 dst->utok.groups = NULL;
1718         }
1719
1720         /* We must have a security_token as otherwise the lossy
1721          * conversion without nss_token would cause create_local_token
1722          * to take the wrong path */
1723         SMB_ASSERT(src->security_token);
1724
1725         dst->session_key = data_blob_talloc( dst, src->session_key.data,
1726                                                 src->session_key.length);
1727
1728         /* This is OK because this functions is only used for the
1729          * GUEST account, which has all-zero keys for both values */
1730         dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1731                                                 src->session_key.length);
1732
1733         status = copy_netr_SamInfo3(dst,
1734                                     server_info->info3,
1735                                     &dst->info3);
1736         if (!NT_STATUS_IS_OK(status)) {
1737                 TALLOC_FREE(dst);
1738                 return NULL;
1739         }
1740
1741         dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1742         if (!dst->unix_name) {
1743                 TALLOC_FREE(dst);
1744                 return NULL;
1745         }
1746
1747         dst->cached_session_info = src;
1748         return dst;
1749 }
1750
1751 /*
1752  * Set a new session key. Used in the rpc server where we have to override the
1753  * SMB level session key with SystemLibraryDTC
1754  */
1755
1756 bool session_info_set_session_key(struct auth_session_info *info,
1757                                  DATA_BLOB session_key)
1758 {
1759         TALLOC_FREE(info->session_key.data);
1760
1761         info->session_key = data_blob_talloc(
1762                 info, session_key.data, session_key.length);
1763
1764         return (info->session_key.data != NULL);
1765 }
1766
1767 static struct auth_session_info *guest_info = NULL;
1768 static struct auth_session_info *anonymous_info = NULL;
1769
1770 static struct auth_serversupplied_info *guest_server_info = NULL;
1771
1772 bool init_guest_session_info(TALLOC_CTX *mem_ctx)
1773 {
1774         NTSTATUS status;
1775
1776         if (guest_info != NULL)
1777                 return true;
1778
1779         status = make_new_session_info_guest(mem_ctx,
1780                                              &guest_info,
1781                                              &guest_server_info);
1782         if (!NT_STATUS_IS_OK(status)) {
1783                 return false;
1784         }
1785
1786         status = make_new_session_info_anonymous(mem_ctx,
1787                                                  &anonymous_info);
1788         if (!NT_STATUS_IS_OK(status)) {
1789                 return false;
1790         }
1791
1792         return true;
1793 }
1794
1795 bool reinit_guest_session_info(TALLOC_CTX *mem_ctx)
1796 {
1797         TALLOC_FREE(guest_info);
1798         TALLOC_FREE(guest_server_info);
1799         TALLOC_FREE(anonymous_info);
1800
1801         DBG_DEBUG("Reinitialing guest info\n");
1802
1803         return init_guest_session_info(mem_ctx);
1804 }
1805
1806 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1807                                 struct auth_serversupplied_info **server_info)
1808 {
1809         /* This is trickier than it would appear to need to be because
1810          * we are trying to avoid certain costly operations when the
1811          * structure is converted to a 'auth_session_info' again in
1812          * create_local_token() */
1813         *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1814         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1815 }
1816
1817 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1818                                 struct auth_session_info **session_info)
1819 {
1820         *session_info = copy_session_info(mem_ctx, guest_info);
1821         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1822 }
1823
1824 NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx,
1825                                     struct auth_serversupplied_info **server_info)
1826 {
1827         if (anonymous_info == NULL) {
1828                 return NT_STATUS_UNSUCCESSFUL;
1829         }
1830
1831         /*
1832          * This is trickier than it would appear to need to be because
1833          * we are trying to avoid certain costly operations when the
1834          * structure is converted to a 'auth_session_info' again in
1835          * create_local_token()
1836          *
1837          * We use a guest server_info, but with the anonymous session info,
1838          * which means create_local_token() will return a copy
1839          * of the anonymous token.
1840          *
1841          * The server info is just used as legacy in order to
1842          * keep existing code working. Maybe some debug messages
1843          * will still refer to guest instead of anonymous.
1844          */
1845         *server_info = copy_session_info_serverinfo_guest(mem_ctx, anonymous_info,
1846                                                           guest_server_info);
1847         if (*server_info == NULL) {
1848                 return NT_STATUS_NO_MEMORY;
1849         }
1850
1851         return NT_STATUS_OK;
1852 }
1853
1854 NTSTATUS make_session_info_anonymous(TALLOC_CTX *mem_ctx,
1855                                      struct auth_session_info **session_info)
1856 {
1857         if (anonymous_info == NULL) {
1858                 return NT_STATUS_UNSUCCESSFUL;
1859         }
1860
1861         *session_info = copy_session_info(mem_ctx, anonymous_info);
1862         if (*session_info == NULL) {
1863                 return NT_STATUS_NO_MEMORY;
1864         }
1865
1866         return NT_STATUS_OK;
1867 }
1868
1869 static struct auth_session_info *system_info = NULL;
1870
1871 NTSTATUS init_system_session_info(TALLOC_CTX *mem_ctx)
1872 {
1873         if (system_info != NULL)
1874                 return NT_STATUS_OK;
1875
1876         return make_new_session_info_system(mem_ctx, &system_info);
1877 }
1878
1879 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1880                                 struct auth_session_info **session_info)
1881 {
1882         if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1883         *session_info = copy_session_info(mem_ctx, system_info);
1884         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1885 }
1886
1887 const struct auth_session_info *get_session_info_system(void)
1888 {
1889     return system_info;
1890 }
1891
1892 /***************************************************************************
1893  Purely internal function for make_server_info_info3
1894 ***************************************************************************/
1895
1896 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1897                               const char *username,
1898                               const struct dom_sid *sid,
1899                               char **found_username,
1900                               struct passwd **pwd,
1901                               bool *username_was_mapped)
1902 {
1903         char *orig_dom_user = NULL;
1904         char *dom_user = NULL;
1905         char *lower_username = NULL;
1906         char *real_username = NULL;
1907         struct passwd *passwd;
1908
1909         lower_username = talloc_strdup(mem_ctx, username);
1910         if (!lower_username) {
1911                 return NT_STATUS_NO_MEMORY;
1912         }
1913         if (!strlower_m( lower_username )) {
1914                 return NT_STATUS_INVALID_PARAMETER;
1915         }
1916
1917         orig_dom_user = talloc_asprintf(mem_ctx,
1918                                 "%s%c%s",
1919                                 domain,
1920                                 *lp_winbind_separator(),
1921                                 lower_username);
1922         if (!orig_dom_user) {
1923                 return NT_STATUS_NO_MEMORY;
1924         }
1925
1926         /* Get the passwd struct.  Try to create the account if necessary. */
1927
1928         *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1929         if (!dom_user) {
1930                 return NT_STATUS_NO_MEMORY;
1931         }
1932
1933         passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
1934         if (!passwd && !*username_was_mapped) {
1935                 struct dom_sid_buf buf;
1936                 uid_t uid;
1937                 bool ok;
1938
1939                 DBG_DEBUG("Failed to find authenticated user %s via "
1940                           "getpwnam(), fallback to sid_to_uid(%s).\n",
1941                           dom_user, dom_sid_str_buf(sid, &buf));
1942
1943                 ok = sid_to_uid(sid, &uid);
1944                 if (!ok) {
1945                         DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
1946                                 dom_sid_str_buf(sid, &buf), dom_user);
1947                         return NT_STATUS_NO_SUCH_USER;
1948                 }
1949                 passwd = getpwuid_alloc(mem_ctx, uid);
1950                 if (!passwd) {
1951                         DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
1952                                 (long long)uid,
1953                                 dom_sid_str_buf(sid, &buf),
1954                                 dom_user);
1955                         return NT_STATUS_NO_SUCH_USER;
1956                 }
1957                 real_username = talloc_strdup(mem_ctx, passwd->pw_name);
1958         }
1959         if (!passwd) {
1960                 DEBUG(3, ("Failed to find authenticated user %s via "
1961                           "getpwnam(), denying access.\n", dom_user));
1962                 return NT_STATUS_NO_SUCH_USER;
1963         }
1964
1965         if (!real_username) {
1966                 return NT_STATUS_NO_MEMORY;
1967         }
1968
1969         *pwd = passwd;
1970
1971         /* This is pointless -- there is no support for differing
1972            unix and windows names.  Make sure to always store the
1973            one we actually looked up and succeeded. Have I mentioned
1974            why I hate the 'winbind use default domain' parameter?
1975                                          --jerry              */
1976
1977         *found_username = talloc_strdup( mem_ctx, real_username );
1978
1979         return NT_STATUS_OK;
1980 }
1981
1982 /****************************************************************************
1983  Wrapper to allow the getpwnam() call to strip the domain name and
1984  try again in case a local UNIX user is already there.  Also run through
1985  the username if we fallback to the username only.
1986  ****************************************************************************/
1987
1988 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1989                              char **p_save_username, bool create )
1990 {
1991         struct passwd *pw = NULL;
1992         char *p = NULL;
1993         const char *username = NULL;
1994
1995         /* we only save a copy of the username it has been mangled
1996            by winbindd use default domain */
1997         *p_save_username = NULL;
1998
1999         /* don't call map_username() here since it has to be done higher
2000            up the stack so we don't call it multiple times */
2001
2002         username = talloc_strdup(mem_ctx, domuser);
2003         if (!username) {
2004                 return NULL;
2005         }
2006
2007         p = strchr_m( username, *lp_winbind_separator() );
2008
2009         /* code for a DOMAIN\user string */
2010
2011         if ( p ) {
2012                 const char *domain = NULL;
2013
2014                 /* split the domain and username into 2 strings */
2015                 *p = '\0';
2016                 domain = username;
2017                 p++;
2018                 username = p;
2019
2020                 if (strequal(domain, get_global_sam_name())) {
2021                         /*
2022                          * This typically don't happen
2023                          * as check_sam_Security()
2024                          * don't call make_server_info_info3()
2025                          * and thus check_account().
2026                          *
2027                          * But we better keep this.
2028                          */
2029                         goto username_only;
2030                 }
2031
2032                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
2033                 if (pw == NULL) {
2034                         return NULL;
2035                 }
2036                 /* make sure we get the case of the username correct */
2037                 /* work around 'winbind use default domain = yes' */
2038
2039                 if ( lp_winbind_use_default_domain() &&
2040                      !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
2041                         *p_save_username = talloc_asprintf(mem_ctx,
2042                                                         "%s%c%s",
2043                                                         domain,
2044                                                         *lp_winbind_separator(),
2045                                                         pw->pw_name);
2046                         if (!*p_save_username) {
2047                                 TALLOC_FREE(pw);
2048                                 return NULL;
2049                         }
2050                 } else {
2051                         *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
2052                 }
2053
2054                 /* whew -- done! */
2055                 return pw;
2056
2057         }
2058
2059         /* just lookup a plain username */
2060 username_only:
2061         pw = Get_Pwnam_alloc(mem_ctx, username);
2062
2063         /* Create local user if requested but only if winbindd
2064            is not running.  We need to protect against cases
2065            where winbindd is failing and then prematurely
2066            creating users in /etc/passwd */
2067
2068         if ( !pw && create && !winbind_ping() ) {
2069                 /* Don't add a machine account. */
2070                 if (username[strlen(username)-1] == '$')
2071                         return NULL;
2072
2073                 _smb_create_user(NULL, username, NULL);
2074                 pw = Get_Pwnam_alloc(mem_ctx, username);
2075         }
2076
2077         /* one last check for a valid passwd struct */
2078
2079         if (pw) {
2080                 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
2081         }
2082         return pw;
2083 }
2084
2085 /***************************************************************************
2086  Make a server_info struct from the info3 returned by a domain logon
2087 ***************************************************************************/
2088
2089 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
2090                                 const char *sent_nt_username,
2091                                 const char *domain,
2092                                 struct auth_serversupplied_info **server_info,
2093                                 const struct netr_SamInfo3 *info3)
2094 {
2095         NTSTATUS nt_status;
2096         char *found_username = NULL;
2097         const char *nt_domain;
2098         const char *nt_username;
2099         struct dom_sid user_sid;
2100         struct dom_sid group_sid;
2101         bool username_was_mapped;
2102         struct passwd *pwd;
2103         struct auth_serversupplied_info *result;
2104         struct dom_sid sid;
2105         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2106
2107         /*
2108            Here is where we should check the list of
2109            trusted domains, and verify that the SID
2110            matches.
2111         */
2112
2113         if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
2114                 nt_status = NT_STATUS_INVALID_PARAMETER;
2115                 goto out;
2116         }
2117
2118         if (!sid_compose(&group_sid, info3->base.domain_sid,
2119                          info3->base.primary_gid)) {
2120                 nt_status = NT_STATUS_INVALID_PARAMETER;
2121                 goto out;
2122         }
2123
2124         nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
2125         if (!nt_username) {
2126                 /* If the server didn't give us one, just use the one we sent
2127                  * them */
2128                 nt_username = sent_nt_username;
2129         }
2130
2131         nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
2132         if (!nt_domain) {
2133                 /* If the server didn't give us one, just use the one we sent
2134                  * them */
2135                 nt_domain = domain;
2136         }
2137
2138         /* If getpwnam() fails try the add user script (2.2.x behavior).
2139
2140            We use the _unmapped_ username here in an attempt to provide
2141            consistent username mapping behavior between kerberos and NTLM[SSP]
2142            authentication in domain mode security.  I.E. Username mapping
2143            should be applied to the fully qualified username
2144            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
2145            called map_username() unnecessarily in make_user_info_map() but
2146            that is how the current code is designed.  Making the change here
2147            is the least disruptive place.  -- jerry */
2148
2149         /* this call will try to create the user if necessary */
2150
2151         sid_copy(&sid, info3->base.domain_sid);
2152         sid_append_rid(&sid, info3->base.rid);
2153
2154         nt_status = check_account(tmp_ctx,
2155                                   nt_domain,
2156                                   nt_username,
2157                                   &sid,
2158                                   &found_username,
2159                                   &pwd,
2160                                   &username_was_mapped);
2161
2162         if (!NT_STATUS_IS_OK(nt_status)) {
2163                 /* Handle 'map to guest = Bad Uid */
2164                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
2165                     (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2166                     lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
2167                         DBG_NOTICE("Try to map %s to guest account\n",
2168                                    nt_username);
2169                         nt_status = make_server_info_guest(tmp_ctx, &result);
2170                         if (NT_STATUS_IS_OK(nt_status)) {
2171                                 *server_info = talloc_move(mem_ctx, &result);
2172                         }
2173                 }
2174                 goto out;
2175         } else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2176                    !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) {
2177                 /*
2178                  * !is_myname(domain) because when smbd starts tries to setup
2179                  * the guest user info, calling this function with nobody
2180                  * username. Nobody is usually uid 65535 but it can be changed
2181                  * to a regular user with 'guest account' parameter
2182                  */
2183                 nt_status = NT_STATUS_INVALID_TOKEN;
2184                 DBG_NOTICE("Username '%s%s%s' is invalid on this system, "
2185                            "it does not meet 'min domain uid' "
2186                            "restriction (%u < %u): %s\n",
2187                            nt_domain, lp_winbind_separator(), nt_username,
2188                            pwd->pw_uid, lp_min_domain_uid(),
2189                            nt_errstr(nt_status));
2190                 goto out;
2191         }
2192
2193         result = make_server_info(tmp_ctx);
2194         if (result == NULL) {
2195                 DEBUG(4, ("make_server_info failed!\n"));
2196                 nt_status = NT_STATUS_NO_MEMORY;
2197                 goto out;
2198         }
2199
2200         result->unix_name = talloc_strdup(result, found_username);
2201
2202         /* copy in the info3 */
2203         nt_status = copy_netr_SamInfo3(result,
2204                                        info3,
2205                                        &result->info3);
2206         if (!NT_STATUS_IS_OK(nt_status)) {
2207                 goto out;
2208         }
2209
2210         /* Fill in the unix info we found on the way */
2211
2212         result->utok.uid = pwd->pw_uid;
2213         result->utok.gid = pwd->pw_gid;
2214
2215         /* ensure we are never given NULL session keys */
2216
2217         if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
2218                 result->session_key = data_blob_null;
2219         } else {
2220                 result->session_key = data_blob_talloc(
2221                         result, info3->base.key.key,
2222                         sizeof(info3->base.key.key));
2223         }
2224
2225         if (all_zero(info3->base.LMSessKey.key,
2226                      sizeof(info3->base.LMSessKey.key))) {
2227                 result->lm_session_key = data_blob_null;
2228         } else {
2229                 result->lm_session_key = data_blob_talloc(
2230                         result, info3->base.LMSessKey.key,
2231                         sizeof(info3->base.LMSessKey.key));
2232         }
2233
2234         result->nss_token |= username_was_mapped;
2235
2236         result->guest = (info3->base.user_flags & NETLOGON_GUEST);
2237
2238         *server_info = talloc_move(mem_ctx, &result);
2239
2240         nt_status = NT_STATUS_OK;
2241 out:
2242         talloc_free(tmp_ctx);
2243
2244         return nt_status;
2245 }
2246
2247 /*****************************************************************************
2248  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
2249 ******************************************************************************/
2250
2251 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
2252                                           const char *sent_nt_username,
2253                                           const char *domain,
2254                                           const struct wbcAuthUserInfo *info,
2255                                           struct auth_serversupplied_info **server_info)
2256 {
2257         struct netr_SamInfo3 info3;
2258         struct netr_SamInfo6 *info6;
2259
2260         info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
2261         if (!info6) {
2262                 return NT_STATUS_NO_MEMORY;
2263         }
2264
2265         info3.base = info6->base;
2266         info3.sidcount = info6->sidcount;
2267         info3.sids = info6->sids;
2268
2269         return make_server_info_info3(mem_ctx,
2270                                       sent_nt_username, domain,
2271                                       server_info, &info3);
2272 }
2273
2274 /**
2275  * Verify whether or not given domain is trusted.
2276  *
2277  * This should only be used on a DC.
2278  *
2279  * @param domain_name name of the domain to be verified
2280  * @return true if domain is one of the trusted ones or
2281  *         false if otherwise
2282  **/
2283
2284 bool is_trusted_domain(const char* dom_name)
2285 {
2286         bool ret;
2287
2288         if (!IS_DC) {
2289                 return false;
2290         }
2291
2292         if (dom_name == NULL || dom_name[0] == '\0') {
2293                 return false;
2294         }
2295
2296         if (strequal(dom_name, get_global_sam_name())) {
2297                 return false;
2298         }
2299
2300         become_root();
2301         DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2302                   "[%s]\n", dom_name ));
2303         ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2304         unbecome_root();
2305
2306         return ret;
2307 }
2308
2309
2310
2311 /*
2312   on a logon error possibly map the error to success if "map to guest"
2313   is set appropriately
2314 */
2315 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
2316                                      NTSTATUS status,
2317                                      const char *user,
2318                                      const char *domain,
2319                                      struct auth_serversupplied_info **server_info)
2320 {
2321         user = user ? user : "";
2322         domain = domain ? domain : "";
2323
2324         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2325                 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
2326                     (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
2327                         DEBUG(3,("No such user %s [%s] - using guest account\n",
2328                                  user, domain));
2329                         return make_server_info_guest(mem_ctx, server_info);
2330                 }
2331         } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2332                 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
2333                         DEBUG(3,("Registered username %s for guest access\n",
2334                                 user));
2335                         return make_server_info_guest(mem_ctx, server_info);
2336                 }
2337         }
2338
2339         return status;
2340 }
2341
2342 /*
2343   Extract session key from a session info and return it in a blob
2344   if intent is KEY_USE_16BYTES, truncate it to 16 bytes
2345
2346   See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
2347   Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
2348
2349   Note that returned session_key is referencing the original key, it is supposed to be
2350   short-lived. If original session_info->session_key is gone, the reference will be broken.
2351 */
2352 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
2353 {
2354
2355         if (session_key == NULL || session_info == NULL) {
2356                 return NT_STATUS_INVALID_PARAMETER;
2357         }
2358
2359         if (session_info->session_key.length == 0) {
2360                 return NT_STATUS_NO_USER_SESSION_KEY;
2361         }
2362
2363         *session_key = session_info->session_key;
2364         if (intent == KEY_USE_16BYTES) {
2365                 session_key->length = MIN(session_info->session_key.length, 16);
2366         }
2367         return NT_STATUS_OK;
2368 }