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