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