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