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