s3-auth Fix spelling
[amitay/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                             struct auth_session_info **session_info_out)
461 {
462         struct security_token *t;
463         NTSTATUS status;
464         size_t i;
465         struct dom_sid tmp_sid;
466         struct auth_session_info *session_info;
467         struct wbcUnixId *ids;
468
469         /* Ensure we can't possible take a code path leading to a
470          * null defref. */
471         if (!server_info) {
472                 return NT_STATUS_LOGON_FAILURE;
473         }
474
475         session_info = talloc_zero(mem_ctx, struct auth_session_info);
476         if (!session_info) {
477                 return NT_STATUS_NO_MEMORY;
478         }
479
480         session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
481         if (!session_info->unix_token) {
482                 TALLOC_FREE(session_info);
483                 return NT_STATUS_NO_MEMORY;
484         }
485
486         session_info->unix_token->uid = server_info->utok.uid;
487         session_info->unix_token->gid = server_info->utok.gid;
488
489         session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
490         if (!session_info->unix_info) {
491                 TALLOC_FREE(session_info);
492                 return NT_STATUS_NO_MEMORY;
493         }
494
495         session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
496         if (!session_info->unix_info->unix_name) {
497                 TALLOC_FREE(session_info);
498                 return NT_STATUS_NO_MEMORY;
499         }
500
501         session_info->unix_info->sanitized_username = talloc_strdup(session_info, server_info->sanitized_username);
502         if (!session_info->unix_info->sanitized_username) {
503                 TALLOC_FREE(session_info);
504                 return NT_STATUS_NO_MEMORY;
505         }
506
507         session_info->unix_info->system = server_info->system;
508
509         if (session_key) {
510                 data_blob_free(&session_info->session_key);
511                 session_info->session_key = data_blob_talloc(session_info,
512                                                                   session_key->data,
513                                                                   session_key->length);
514                 if (!session_info->session_key.data && session_key->length) {
515                         return NT_STATUS_NO_MEMORY;
516                 }
517         } else {
518                 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
519                                                               server_info->session_key.length);
520         }
521
522         if (session_info->security_token) {
523                 /* Just copy the token, it has already been finalised
524                  * (nasty hack to support a cached guest session_info,
525                  * and a possible strategy for auth_samba4 to pass in
526                  * a finalised session) */
527
528                 session_info->security_token = dup_nt_token(session_info, server_info->security_token);
529                 if (!session_info->security_token) {
530                         TALLOC_FREE(session_info);
531                         return NT_STATUS_NO_MEMORY;
532                 }
533
534                 session_info->unix_token->ngroups = server_info->utok.ngroups;
535                 if (server_info->utok.ngroups != 0) {
536                         session_info->unix_token->groups = (gid_t *)talloc_memdup(
537                                 session_info->unix_token, server_info->utok.groups,
538                                 sizeof(gid_t)*session_info->unix_token->ngroups);
539                 } else {
540                         session_info->unix_token->groups = NULL;
541                 }
542
543                 *session_info_out = session_info;
544                 return NT_STATUS_OK;
545         }
546
547         /* We need to populate session_info->info with the information found in server_info->info3 */
548         status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
549                                             server_info->guest == false,
550                                             &session_info->info);
551         if (!NT_STATUS_IS_OK(status)) {
552                 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
553                 TALLOC_FREE(session_info);
554                 return status;
555         }
556
557         /*
558          * If winbind is not around, we can not make much use of the SIDs the
559          * domain controller provided us with. Likewise if the user name was
560          * mapped to some local unix user.
561          */
562
563         if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
564             (server_info->nss_token)) {
565                 status = create_token_from_username(session_info,
566                                                     server_info->unix_name,
567                                                     server_info->guest,
568                                                     &session_info->unix_token->uid,
569                                                     &session_info->unix_token->gid,
570                                                     &session_info->unix_info->unix_name,
571                                                     &session_info->security_token);
572
573         } else {
574                 status = create_local_nt_token_from_info3(session_info,
575                                                           server_info->guest,
576                                                           server_info->info3,
577                                                           &server_info->extra,
578                                                           &session_info->security_token);
579         }
580
581         if (!NT_STATUS_IS_OK(status)) {
582                 return status;
583         }
584
585         /* Convert the SIDs to gids. */
586
587         session_info->unix_token->ngroups = 0;
588         session_info->unix_token->groups = NULL;
589
590         t = session_info->security_token;
591
592         ids = talloc_array(talloc_tos(), struct wbcUnixId,
593                            t->num_sids);
594         if (ids == NULL) {
595                 return NT_STATUS_NO_MEMORY;
596         }
597
598         if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) {
599                 TALLOC_FREE(ids);
600                 return NT_STATUS_NO_MEMORY;
601         }
602
603         /* Start at index 1, where the groups start. */
604
605         for (i=1; i<t->num_sids; i++) {
606
607                 if (ids[i].type != WBC_ID_TYPE_GID) {
608                         DEBUG(10, ("Could not convert SID %s to gid, "
609                                    "ignoring it\n",
610                                    sid_string_dbg(&t->sids[i])));
611                         continue;
612                 }
613                 if (!add_gid_to_array_unique(session_info, ids[i].id.gid,
614                                              &session_info->unix_token->groups,
615                                              &session_info->unix_token->ngroups)) {
616                         return NT_STATUS_NO_MEMORY;
617                 }
618         }
619
620         /*
621          * Add the "Unix Group" SID for each gid to catch mapped groups
622          * and their Unix equivalent.  This is to solve the backwards
623          * compatibility problem of 'valid users = +ntadmin' where
624          * ntadmin has been paired with "Domain Admins" in the group
625          * mapping table.  Otherwise smb.conf would need to be changed
626          * to 'valid user = "Domain Admins"'.  --jerry
627          *
628          * For consistency we also add the "Unix User" SID,
629          * so that the complete unix token is represented within
630          * the nt token.
631          */
632
633         uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
634
635         add_sid_to_array_unique(session_info->security_token, &tmp_sid,
636                                 &session_info->security_token->sids,
637                                 &session_info->security_token->num_sids);
638
639         for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
640                 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
641                 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
642                                         &session_info->security_token->sids,
643                                         &session_info->security_token->num_sids);
644         }
645
646         security_token_debug(DBGC_AUTH, 10, session_info->security_token);
647         debug_unix_user_token(DBGC_AUTH, 10,
648                               session_info->unix_token->uid,
649                               session_info->unix_token->gid,
650                               session_info->unix_token->ngroups,
651                               session_info->unix_token->groups);
652
653         status = log_nt_token(session_info->security_token);
654         if (!NT_STATUS_IS_OK(status)) {
655                 return status;
656         }
657
658         *session_info_out = session_info;
659         return NT_STATUS_OK;
660 }
661
662 /***************************************************************************
663  Make (and fill) a server_info struct from a 'struct passwd' by conversion
664  to a struct samu
665 ***************************************************************************/
666
667 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
668                              char *unix_username,
669                              struct passwd *pwd)
670 {
671         NTSTATUS status;
672         struct samu *sampass = NULL;
673         char *qualified_name = NULL;
674         TALLOC_CTX *mem_ctx = NULL;
675         struct dom_sid u_sid;
676         enum lsa_SidType type;
677         struct auth_serversupplied_info *result;
678
679         /*
680          * The SID returned in server_info->sam_account is based
681          * on our SAM sid even though for a pure UNIX account this should
682          * not be the case as it doesn't really exist in the SAM db.
683          * This causes lookups on "[in]valid users" to fail as they
684          * will lookup this name as a "Unix User" SID to check against
685          * the user token. Fix this by adding the "Unix User"\unix_username
686          * SID to the sid array. The correct fix should probably be
687          * changing the server_info->sam_account user SID to be a
688          * S-1-22 Unix SID, but this might break old configs where
689          * plaintext passwords were used with no SAM backend.
690          */
691
692         mem_ctx = talloc_init("make_server_info_pw_tmp");
693         if (!mem_ctx) {
694                 return NT_STATUS_NO_MEMORY;
695         }
696
697         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
698                                         unix_users_domain_name(),
699                                         unix_username );
700         if (!qualified_name) {
701                 TALLOC_FREE(mem_ctx);
702                 return NT_STATUS_NO_MEMORY;
703         }
704
705         if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
706                                                 NULL, NULL,
707                                                 &u_sid, &type)) {
708                 TALLOC_FREE(mem_ctx);
709                 return NT_STATUS_NO_SUCH_USER;
710         }
711
712         TALLOC_FREE(mem_ctx);
713
714         if (type != SID_NAME_USER) {
715                 return NT_STATUS_NO_SUCH_USER;
716         }
717
718         if ( !(sampass = samu_new( NULL )) ) {
719                 return NT_STATUS_NO_MEMORY;
720         }
721
722         status = samu_set_unix( sampass, pwd );
723         if (!NT_STATUS_IS_OK(status)) {
724                 return status;
725         }
726
727         /* In pathological cases the above call can set the account
728          * name to the DOMAIN\username form. Reset the account name
729          * using unix_username */
730         pdb_set_username(sampass, unix_username, PDB_SET);
731
732         /* set the user sid to be the calculated u_sid */
733         pdb_set_user_sid(sampass, &u_sid, PDB_SET);
734
735         result = make_server_info(NULL);
736         if (result == NULL) {
737                 TALLOC_FREE(sampass);
738                 return NT_STATUS_NO_MEMORY;
739         }
740
741         status = samu_to_SamInfo3(result, sampass, lp_netbios_name(),
742                                   &result->info3, &result->extra);
743         TALLOC_FREE(sampass);
744         if (!NT_STATUS_IS_OK(status)) {
745                 DEBUG(10, ("Failed to convert samu to info3: %s\n",
746                            nt_errstr(status)));
747                 TALLOC_FREE(result);
748                 return status;
749         }
750
751         result->unix_name = talloc_strdup(result, unix_username);
752         result->sanitized_username = sanitize_username(result, unix_username);
753
754         if ((result->unix_name == NULL)
755             || (result->sanitized_username == NULL)) {
756                 TALLOC_FREE(result);
757                 return NT_STATUS_NO_MEMORY;
758         }
759
760         result->utok.uid = pwd->pw_uid;
761         result->utok.gid = pwd->pw_gid;
762
763         *server_info = result;
764
765         return NT_STATUS_OK;
766 }
767
768 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
769                                 struct netr_SamInfo3 *info3)
770 {
771         const char *guest_account = lp_guestaccount();
772         struct dom_sid domain_sid;
773         struct passwd *pwd;
774         const char *tmp;
775
776         pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
777         if (pwd == NULL) {
778                 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
779                          "account [%s]!\n", guest_account));
780                 return NT_STATUS_NO_SUCH_USER;
781         }
782
783         /* Set account name */
784         tmp = talloc_strdup(mem_ctx, pwd->pw_name);
785         if (tmp == NULL) {
786                 return NT_STATUS_NO_MEMORY;
787         }
788         init_lsa_String(&info3->base.account_name, tmp);
789
790         /* Set domain name */
791         tmp = talloc_strdup(mem_ctx, get_global_sam_name());
792         if (tmp == NULL) {
793                 return NT_STATUS_NO_MEMORY;
794         }
795         init_lsa_StringLarge(&info3->base.domain, tmp);
796
797         /* Domain sid */
798         sid_copy(&domain_sid, get_global_sam_sid());
799
800         info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
801         if (info3->base.domain_sid == NULL) {
802                 return NT_STATUS_NO_MEMORY;
803         }
804
805         /* Guest rid */
806         info3->base.rid = DOMAIN_RID_GUEST;
807
808         /* Primary gid */
809         info3->base.primary_gid = BUILTIN_RID_GUESTS;
810
811         /* Set as guest */
812         info3->base.user_flags = NETLOGON_GUEST;
813
814         TALLOC_FREE(pwd);
815         return NT_STATUS_OK;
816 }
817
818 /***************************************************************************
819  Make (and fill) a user_info struct for a guest login.
820  This *must* succeed for smbd to start. If there is no mapping entry for
821  the guest gid, then create one.
822
823  The resulting structure is a 'session_info' because
824  create_local_token() has already been called on it.  This is quite
825  nasty, as the auth subsystem isn't expect this, but the behavior is
826  left as-is for now.
827 ***************************************************************************/
828
829 static NTSTATUS make_new_session_info_guest(struct auth_session_info **session_info, struct auth_serversupplied_info **server_info)
830 {
831         static const char zeros[16] = {0};
832         const char *guest_account = lp_guestaccount();
833         const char *domain = lp_netbios_name();
834         struct netr_SamInfo3 info3;
835         TALLOC_CTX *tmp_ctx;
836         NTSTATUS status;
837         fstring tmp;
838
839         tmp_ctx = talloc_stackframe();
840         if (tmp_ctx == NULL) {
841                 return NT_STATUS_NO_MEMORY;
842         }
843
844         ZERO_STRUCT(info3);
845
846         status = get_guest_info3(tmp_ctx, &info3);
847         if (!NT_STATUS_IS_OK(status)) {
848                 DEBUG(0, ("get_guest_info3 failed with %s\n",
849                           nt_errstr(status)));
850                 goto done;
851         }
852
853         status = make_server_info_info3(tmp_ctx,
854                                         guest_account,
855                                         domain,
856                                         server_info,
857                                         &info3);
858         if (!NT_STATUS_IS_OK(status)) {
859                 DEBUG(0, ("make_server_info_info3 failed with %s\n",
860                           nt_errstr(status)));
861                 goto done;
862         }
863
864         (*server_info)->guest = True;
865
866         /* This should not be done here (we should produce a server
867          * info, and later construct a session info from it), but for
868          * now this does not change the previous behavior */
869         status = create_local_token(tmp_ctx, *server_info, NULL, session_info);
870         if (!NT_STATUS_IS_OK(status)) {
871                 DEBUG(0, ("create_local_token failed: %s\n",
872                           nt_errstr(status)));
873                 goto done;
874         }
875         talloc_steal(NULL, *session_info);
876         talloc_steal(NULL, *server_info);
877
878         /* annoying, but the Guest really does have a session key, and it is
879            all zeros! */
880         (*session_info)->session_key = data_blob(zeros, sizeof(zeros));
881
882         alpha_strcpy(tmp, (*server_info)->info3->base.account_name.string,
883                      ". _-$", sizeof(tmp));
884         (*session_info)->unix_info->sanitized_username = talloc_strdup(*session_info, tmp);
885
886         status = NT_STATUS_OK;
887 done:
888         TALLOC_FREE(tmp_ctx);
889         return status;
890 }
891
892 /***************************************************************************
893  Make (and fill) a auth_session_info struct for a system user login.
894  This *must* succeed for smbd to start.
895 ***************************************************************************/
896
897 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
898                                             struct auth_session_info **session_info)
899 {
900         struct passwd *pwd;
901         NTSTATUS status;
902
903         pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
904         if (pwd == NULL) {
905                 return NT_STATUS_NO_SUCH_USER;
906         }
907
908         status = make_session_info_from_username(mem_ctx,
909                                                  pwd->pw_name,
910                                                  false,
911                                                  session_info);
912         TALLOC_FREE(pwd);
913         if (!NT_STATUS_IS_OK(status)) {
914                 return status;
915         }
916
917         (*session_info)->unix_info->system = true;
918
919         status = add_sid_to_array_unique((*session_info)->security_token->sids,
920                                          &global_sid_System,
921                                          &(*session_info)->security_token->sids,
922                                          &(*session_info)->security_token->num_sids);
923         if (!NT_STATUS_IS_OK(status)) {
924                 TALLOC_FREE((*session_info));
925                 return status;
926         }
927
928         return NT_STATUS_OK;
929 }
930
931 /****************************************************************************
932   Fake a auth_session_info just from a username (as a
933   session_info structure, with create_local_token() already called on
934   it.
935 ****************************************************************************/
936
937 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
938                                          const char *username,
939                                          bool is_guest,
940                                          struct auth_session_info **session_info)
941 {
942         struct auth_serversupplied_info *result;
943         struct passwd *pwd;
944         NTSTATUS status;
945
946         pwd = Get_Pwnam_alloc(talloc_tos(), username);
947         if (pwd == NULL) {
948                 return NT_STATUS_NO_SUCH_USER;
949         }
950
951         status = make_server_info_pw(&result, pwd->pw_name, pwd);
952
953         TALLOC_FREE(pwd);
954
955         if (!NT_STATUS_IS_OK(status)) {
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, session_info);
964         talloc_free(result);
965         return status;
966 }
967
968 /* This function MUST only used to create the cached server_info for
969  * guest.
970  *
971  * This is a lossy conversion.  Variables known to be lost so far
972  * include:
973  *
974  * - nss_token (not needed because the only read doesn't happen
975  * for the GUEST user, as this routine populates ->security_token
976  *
977  * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
978  *
979  * - The 'server_info' parameter allows the missing 'info3' to be copied across.
980  */
981 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
982                                                                            const struct auth_session_info *src,
983                                                                            struct auth_serversupplied_info *server_info)
984 {
985         struct auth_serversupplied_info *dst;
986
987         dst = make_server_info(mem_ctx);
988         if (dst == NULL) {
989                 return NULL;
990         }
991
992         /* This element must be provided to convert back to an auth_serversupplied_info */
993         SMB_ASSERT(src->unix_info);
994
995         dst->guest = true;
996         dst->system = false;
997
998         /* This element must be provided to convert back to an
999          * auth_serversupplied_info.  This needs to be from the
1000          * auth_session_info because the group values in particular
1001          * may change during create_local_token() processing */
1002         SMB_ASSERT(src->unix_token);
1003         dst->utok.uid = src->unix_token->uid;
1004         dst->utok.gid = src->unix_token->gid;
1005         dst->utok.ngroups = src->unix_token->ngroups;
1006         if (src->unix_token->ngroups != 0) {
1007                 dst->utok.groups = (gid_t *)talloc_memdup(
1008                         dst, src->unix_token->groups,
1009                         sizeof(gid_t)*dst->utok.ngroups);
1010         } else {
1011                 dst->utok.groups = NULL;
1012         }
1013
1014         /* We must have a security_token as otherwise the lossy
1015          * conversion without nss_token would cause create_local_token
1016          * to take the wrong path */
1017         SMB_ASSERT(src->security_token);
1018
1019         dst->security_token = dup_nt_token(dst, src->security_token);
1020         if (!dst->security_token) {
1021                 TALLOC_FREE(dst);
1022                 return NULL;
1023         }
1024
1025         dst->session_key = data_blob_talloc( dst, src->session_key.data,
1026                                                 src->session_key.length);
1027
1028         /* This is OK because this functions is only used for the
1029          * GUEST account, which has all-zero keys for both values */
1030         dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1031                                                 src->session_key.length);
1032
1033         dst->info3 = copy_netr_SamInfo3(dst, server_info->info3);
1034         if (!dst->info3) {
1035                 TALLOC_FREE(dst);
1036                 return NULL;
1037         }
1038
1039         dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1040         if (!dst->unix_name) {
1041                 TALLOC_FREE(dst);
1042                 return NULL;
1043         }
1044
1045         dst->sanitized_username = talloc_strdup(dst, src->unix_info->sanitized_username);
1046         if (!dst->sanitized_username) {
1047                 TALLOC_FREE(dst);
1048                 return NULL;
1049         }
1050
1051         return dst;
1052 }
1053
1054 struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1055                                              const struct auth_session_info *src)
1056 {
1057         struct auth_session_info *dst;
1058         DATA_BLOB blob;
1059         enum ndr_err_code ndr_err;
1060
1061         ndr_err = ndr_push_struct_blob(
1062                 &blob, talloc_tos(), src,
1063                 (ndr_push_flags_fn_t)ndr_push_auth_session_info);
1064         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1065                 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1066                            "%s\n", ndr_errstr(ndr_err)));
1067                 return NULL;
1068         }
1069
1070         dst = talloc(mem_ctx, struct auth_session_info);
1071         if (dst == NULL) {
1072                 DEBUG(0, ("talloc failed\n"));
1073                 TALLOC_FREE(blob.data);
1074                 return NULL;
1075         }
1076
1077         ndr_err = ndr_pull_struct_blob(
1078                 &blob, dst, dst,
1079                 (ndr_pull_flags_fn_t)ndr_pull_auth_session_info);
1080         TALLOC_FREE(blob.data);
1081
1082         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1083                 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1084                            "%s\n", ndr_errstr(ndr_err)));
1085                 TALLOC_FREE(dst);
1086                 return NULL;
1087         }
1088
1089         return dst;
1090 }
1091
1092 /*
1093  * Set a new session key. Used in the rpc server where we have to override the
1094  * SMB level session key with SystemLibraryDTC
1095  */
1096
1097 bool session_info_set_session_key(struct auth_session_info *info,
1098                                  DATA_BLOB session_key)
1099 {
1100         TALLOC_FREE(info->session_key.data);
1101
1102         info->session_key = data_blob_talloc(
1103                 info, session_key.data, session_key.length);
1104
1105         return (info->session_key.data != NULL);
1106 }
1107
1108 static struct auth_session_info *guest_info = NULL;
1109
1110 static struct auth_serversupplied_info *guest_server_info = NULL;
1111
1112 bool init_guest_info(void)
1113 {
1114         if (guest_info != NULL)
1115                 return True;
1116
1117         return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info, &guest_server_info));
1118 }
1119
1120 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1121                                 struct auth_serversupplied_info **server_info)
1122 {
1123         /* This is trickier than it would appear to need to be because
1124          * we are trying to avoid certain costly operations when the
1125          * structure is converted to a 'auth_session_info' again in
1126          * create_local_token() */
1127         *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1128         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1129 }
1130
1131 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1132                                 struct auth_session_info **session_info)
1133 {
1134         *session_info = copy_session_info(mem_ctx, guest_info);
1135         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1136 }
1137
1138 static struct auth_session_info *system_info = NULL;
1139
1140 NTSTATUS init_system_info(void)
1141 {
1142         if (system_info != NULL)
1143                 return NT_STATUS_OK;
1144
1145         return make_new_session_info_system(NULL, &system_info);
1146 }
1147
1148 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1149                                 struct auth_session_info **session_info)
1150 {
1151         if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1152         *session_info = copy_session_info(mem_ctx, system_info);
1153         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1154 }
1155
1156 const struct auth_session_info *get_session_info_system(void)
1157 {
1158     return system_info;
1159 }
1160
1161 bool copy_current_user(struct current_user *dst, struct current_user *src)
1162 {
1163         gid_t *groups;
1164         struct security_token *nt_token;
1165
1166         groups = (gid_t *)memdup(src->ut.groups,
1167                                  sizeof(gid_t) * src->ut.ngroups);
1168         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1169                 return False;
1170         }
1171
1172         nt_token = dup_nt_token(NULL, src->nt_user_token);
1173         if (nt_token == NULL) {
1174                 SAFE_FREE(groups);
1175                 return False;
1176         }
1177
1178         dst->conn = src->conn;
1179         dst->vuid = src->vuid;
1180         dst->ut.uid = src->ut.uid;
1181         dst->ut.gid = src->ut.gid;
1182         dst->ut.ngroups = src->ut.ngroups;
1183         dst->ut.groups = groups;
1184         dst->nt_user_token = nt_token;
1185         return True;
1186 }
1187
1188 /***************************************************************************
1189  Purely internal function for make_server_info_info3
1190 ***************************************************************************/
1191
1192 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1193                               const char *username, char **found_username,
1194                               struct passwd **pwd,
1195                               bool *username_was_mapped)
1196 {
1197         char *orig_dom_user = NULL;
1198         char *dom_user = NULL;
1199         char *lower_username = NULL;
1200         char *real_username = NULL;
1201         struct passwd *passwd;
1202
1203         lower_username = talloc_strdup(mem_ctx, username);
1204         if (!lower_username) {
1205                 return NT_STATUS_NO_MEMORY;
1206         }
1207         strlower_m( lower_username );
1208
1209         orig_dom_user = talloc_asprintf(mem_ctx,
1210                                 "%s%c%s",
1211                                 domain,
1212                                 *lp_winbind_separator(),
1213                                 lower_username);
1214         if (!orig_dom_user) {
1215                 return NT_STATUS_NO_MEMORY;
1216         }
1217
1218         /* Get the passwd struct.  Try to create the account if necessary. */
1219
1220         *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1221         if (!dom_user) {
1222                 return NT_STATUS_NO_MEMORY;
1223         }
1224
1225         passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, True );
1226         if (!passwd) {
1227                 DEBUG(3, ("Failed to find authenticated user %s via "
1228                           "getpwnam(), denying access.\n", dom_user));
1229                 return NT_STATUS_NO_SUCH_USER;
1230         }
1231
1232         if (!real_username) {
1233                 return NT_STATUS_NO_MEMORY;
1234         }
1235
1236         *pwd = passwd;
1237
1238         /* This is pointless -- there is no support for differing
1239            unix and windows names.  Make sure to always store the 
1240            one we actually looked up and succeeded. Have I mentioned
1241            why I hate the 'winbind use default domain' parameter?   
1242                                          --jerry              */
1243
1244         *found_username = talloc_strdup( mem_ctx, real_username );
1245
1246         return NT_STATUS_OK;
1247 }
1248
1249 /****************************************************************************
1250  Wrapper to allow the getpwnam() call to strip the domain name and 
1251  try again in case a local UNIX user is already there.  Also run through 
1252  the username if we fallback to the username only.
1253  ****************************************************************************/
1254
1255 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1256                              char **p_save_username, bool create )
1257 {
1258         struct passwd *pw = NULL;
1259         char *p = NULL;
1260         char *username = NULL;
1261
1262         /* we only save a copy of the username it has been mangled 
1263            by winbindd use default domain */
1264         *p_save_username = NULL;
1265
1266         /* don't call map_username() here since it has to be done higher 
1267            up the stack so we don't call it multiple times */
1268
1269         username = talloc_strdup(mem_ctx, domuser);
1270         if (!username) {
1271                 return NULL;
1272         }
1273
1274         p = strchr_m( username, *lp_winbind_separator() );
1275
1276         /* code for a DOMAIN\user string */
1277
1278         if ( p ) {
1279                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1280                 if ( pw ) {
1281                         /* make sure we get the case of the username correct */
1282                         /* work around 'winbind use default domain = yes' */
1283
1284                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1285                                 char *domain;
1286
1287                                 /* split the domain and username into 2 strings */
1288                                 *p = '\0';
1289                                 domain = username;
1290
1291                                 *p_save_username = talloc_asprintf(mem_ctx,
1292                                                                 "%s%c%s",
1293                                                                 domain,
1294                                                                 *lp_winbind_separator(),
1295                                                                 pw->pw_name);
1296                                 if (!*p_save_username) {
1297                                         TALLOC_FREE(pw);
1298                                         return NULL;
1299                                 }
1300                         } else {
1301                                 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1302                         }
1303
1304                         /* whew -- done! */
1305                         return pw;
1306                 }
1307
1308                 /* setup for lookup of just the username */
1309                 /* remember that p and username are overlapping memory */
1310
1311                 p++;
1312                 username = talloc_strdup(mem_ctx, p);
1313                 if (!username) {
1314                         return NULL;
1315                 }
1316         }
1317
1318         /* just lookup a plain username */
1319
1320         pw = Get_Pwnam_alloc(mem_ctx, username);
1321
1322         /* Create local user if requested but only if winbindd
1323            is not running.  We need to protect against cases
1324            where winbindd is failing and then prematurely
1325            creating users in /etc/passwd */
1326
1327         if ( !pw && create && !winbind_ping() ) {
1328                 /* Don't add a machine account. */
1329                 if (username[strlen(username)-1] == '$')
1330                         return NULL;
1331
1332                 _smb_create_user(NULL, username, NULL);
1333                 pw = Get_Pwnam_alloc(mem_ctx, username);
1334         }
1335
1336         /* one last check for a valid passwd struct */
1337
1338         if (pw) {
1339                 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1340         }
1341         return pw;
1342 }
1343
1344 /***************************************************************************
1345  Make a server_info struct from the info3 returned by a domain logon 
1346 ***************************************************************************/
1347
1348 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1349                                 const char *sent_nt_username,
1350                                 const char *domain,
1351                                 struct auth_serversupplied_info **server_info,
1352                                 struct netr_SamInfo3 *info3)
1353 {
1354         static const char zeros[16] = {0, };
1355
1356         NTSTATUS nt_status = NT_STATUS_OK;
1357         char *found_username = NULL;
1358         const char *nt_domain;
1359         const char *nt_username;
1360         bool username_was_mapped;
1361         struct passwd *pwd;
1362         struct auth_serversupplied_info *result;
1363         struct dom_sid *group_sid;
1364         struct netr_SamInfo3 *i3;
1365
1366         /* 
1367            Here is where we should check the list of
1368            trusted domains, and verify that the SID 
1369            matches.
1370         */
1371
1372         nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1373         if (!nt_username) {
1374                 /* If the server didn't give us one, just use the one we sent
1375                  * them */
1376                 nt_username = sent_nt_username;
1377         }
1378
1379         nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1380         if (!nt_domain) {
1381                 /* If the server didn't give us one, just use the one we sent
1382                  * them */
1383                 nt_domain = domain;
1384         }
1385
1386         /* If getpwnam() fails try the add user script (2.2.x behavior).
1387
1388            We use the _unmapped_ username here in an attempt to provide
1389            consistent username mapping behavior between kerberos and NTLM[SSP]
1390            authentication in domain mode security.  I.E. Username mapping
1391            should be applied to the fully qualified username
1392            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1393            called map_username() unnecessarily in make_user_info_map() but
1394            that is how the current code is designed.  Making the change here
1395            is the least disruptive place.  -- jerry */
1396
1397         /* this call will try to create the user if necessary */
1398
1399         nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
1400                                      &found_username, &pwd,
1401                                      &username_was_mapped);
1402
1403         if (!NT_STATUS_IS_OK(nt_status)) {
1404                 return nt_status;
1405         }
1406
1407         result = make_server_info(NULL);
1408         if (result == NULL) {
1409                 DEBUG(4, ("make_server_info failed!\n"));
1410                 return NT_STATUS_NO_MEMORY;
1411         }
1412
1413         result->unix_name = talloc_strdup(result, found_username);
1414
1415         result->sanitized_username = sanitize_username(result,
1416                                                        result->unix_name);
1417         if (result->sanitized_username == NULL) {
1418                 TALLOC_FREE(result);
1419                 return NT_STATUS_NO_MEMORY;
1420         }
1421
1422         /* copy in the info3 */
1423         result->info3 = i3 = copy_netr_SamInfo3(result, info3);
1424         if (result->info3 == NULL) {
1425                 TALLOC_FREE(result);
1426                 return NT_STATUS_NO_MEMORY;
1427         }
1428
1429         /* Fill in the unix info we found on the way */
1430         result->utok.uid = pwd->pw_uid;
1431         result->utok.gid = pwd->pw_gid;
1432
1433         /* We can't just trust that the primary group sid sent us is something
1434          * we can really use. Obtain the usable sid, and store the original
1435          * one as an additional group if it had to be replaced */
1436         nt_status = get_primary_group_sid(mem_ctx, found_username,
1437                                           &pwd, &group_sid);
1438         if (!NT_STATUS_IS_OK(nt_status)) {
1439                 TALLOC_FREE(result);
1440                 return nt_status;
1441         }
1442
1443         /* store and check if it is the same we got originally */
1444         sid_peek_rid(group_sid, &i3->base.primary_gid);
1445         if (i3->base.primary_gid != info3->base.primary_gid) {
1446                 uint32_t n = i3->base.groups.count;
1447                 /* not the same, store the original as an additional group */
1448                 i3->base.groups.rids =
1449                         talloc_realloc(i3, i3->base.groups.rids,
1450                                         struct samr_RidWithAttribute, n + 1);
1451                 if (i3->base.groups.rids == NULL) {
1452                         TALLOC_FREE(result);
1453                         return NT_STATUS_NO_MEMORY;
1454                 }
1455                 i3->base.groups.rids[n].rid = info3->base.primary_gid;
1456                 i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
1457                 i3->base.groups.count = n + 1;
1458         }
1459
1460         /* ensure we are never given NULL session keys */
1461
1462         if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1463                 result->session_key = data_blob_null;
1464         } else {
1465                 result->session_key = data_blob_talloc(
1466                         result, info3->base.key.key,
1467                         sizeof(info3->base.key.key));
1468         }
1469
1470         if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1471                 result->lm_session_key = data_blob_null;
1472         } else {
1473                 result->lm_session_key = data_blob_talloc(
1474                         result, info3->base.LMSessKey.key,
1475                         sizeof(info3->base.LMSessKey.key));
1476         }
1477
1478         result->nss_token |= username_was_mapped;
1479
1480         result->guest = (info3->base.user_flags & NETLOGON_GUEST);
1481
1482         *server_info = result;
1483
1484         return NT_STATUS_OK;
1485 }
1486
1487 /*****************************************************************************
1488  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1489 ******************************************************************************/
1490
1491 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1492                                           const char *sent_nt_username,
1493                                           const char *domain,
1494                                           const struct wbcAuthUserInfo *info,
1495                                           struct auth_serversupplied_info **server_info)
1496 {
1497         struct netr_SamInfo3 *info3;
1498
1499         info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1500         if (!info3) {
1501                 return NT_STATUS_NO_MEMORY;
1502         }
1503
1504         return make_server_info_info3(mem_ctx,
1505                                       sent_nt_username, domain,
1506                                       server_info, info3);
1507 }
1508
1509 /**
1510  * Verify whether or not given domain is trusted.
1511  *
1512  * @param domain_name name of the domain to be verified
1513  * @return true if domain is one of the trusted ones or
1514  *         false if otherwise
1515  **/
1516
1517 bool is_trusted_domain(const char* dom_name)
1518 {
1519         struct dom_sid trustdom_sid;
1520         bool ret;
1521
1522         /* no trusted domains for a standalone server */
1523
1524         if ( lp_server_role() == ROLE_STANDALONE )
1525                 return False;
1526
1527         if (dom_name == NULL || dom_name[0] == '\0') {
1528                 return false;
1529         }
1530
1531         if (strequal(dom_name, get_global_sam_name())) {
1532                 return false;
1533         }
1534
1535         /* if we are a DC, then check for a direct trust relationships */
1536
1537         if ( IS_DC ) {
1538                 become_root();
1539                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1540                           "[%s]\n", dom_name ));
1541                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1542                 unbecome_root();
1543                 if (ret)
1544                         return True;
1545         }
1546         else {
1547                 wbcErr result;
1548
1549                 /* If winbind is around, ask it */
1550
1551                 result = wb_is_trusted_domain(dom_name);
1552
1553                 if (result == WBC_ERR_SUCCESS) {
1554                         return True;
1555                 }
1556
1557                 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1558                         /* winbind could not find the domain */
1559                         return False;
1560                 }
1561
1562                 /* The only other possible result is that winbind is not up
1563                    and running. We need to update the trustdom_cache
1564                    ourselves */
1565
1566                 update_trustdom_cache();
1567         }
1568
1569         /* now the trustdom cache should be available a DC could still
1570          * have a transitive trust so fall back to the cache of trusted
1571          * domains (like a domain member would use  */
1572
1573         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1574                 return True;
1575         }
1576
1577         return False;
1578 }
1579